Encontré algo, pero eso significa usar CURSOR
DECLARE @ColumnName VARCHAR(200)
DECLARE @ColumnCount INT
DECLARE @sql VARCHAR(400)
CREATE TABLE #tempTable (Id INT)
DECLARE GetNonNullRows CURSOR
FOR
SELECT c.NAME, (SELECT COUNT(*) FROM sys.columns col WHERE col.object_id = c.OBJECT_ID) FROM sys.tables AS t
JOIN sys.columns AS c ON t.object_id = c.object_id
WHERE t.name = 'SomeTable' AND t.type = 'U'
OPEN GetNonNullRows
FETCH NEXT FROM GetNonNullRows INTO @ColumnName, @ColumnCount
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql = 'SELECT st.UniqueId FROM SomeTable AS st WHERE ' + CONVERT(varchar, @ColumnName) + ' IS NOT NULL'
INSERT INTO #tempTable
EXEC (@sql)
FETCH NEXT FROM GetNonNullRows INTO @ColumnName, @ColumnCount
END
CLOSE GetNonNullRows
DEALLOCATE GetNonNullRows
SELECT * FROM SomeTable AS st1
WHERE st1.UniqueId IN (SELECT Id FROM #tempTable AS tt
GROUP BY Id
HAVING COUNT(Id) = @ColumnCount)
DROP TABLE #tempTable
Déjame explicarte esto un poco.
Primero creo un cursor que recorre todas las columnas de una tabla. Para cada columna, he creado un script sql para buscar en la tabla valores no nulos para la columna seleccionada. Para aquellas filas que cumplen con los criterios, tomo su ID único y lo coloco en la tabla temporal, y este trabajo lo estoy usando para todas las columnas.
Al final, solo los ID que cuentan como el número de columnas son su conjunto de resultados, porque solo las filas que tienen el mismo número de apariciones, como el número de columnas en la tabla, pueden ser filas con todos los valores no nulos en todas las columnas.