简体   繁体   English

SQL 遍历表和列以查找哪些列不是空的

[英]SQL Loop through tables and columns to find which columns are NOT empty

I created a temp table #test containing 3 fields: ColumnName, TableName, and Id.我创建了一个包含 3 个字段的临时表 #test:ColumnName、TableName 和 Id。 I would like to see which rows in the #test table (columns in their respective tables) are not empty?我想看看#test 表中的哪些行(它们各自表中的列)不是空的? Ie, for every column name that i have in the ColumnName field, and for the corresponding table found in the TableName field, i would like to see whether the column is empty or not.即,对于 ColumnName 字段中的每个列名,以及在 TableName 字段中找到的相应表,我想查看该列是否为空。 Tried some things (see below) but didn't get anywhere.尝试了一些东西(见下文),但一无所获。 Help, please.请帮忙。

declare @LoopCounter INT = 1, @maxloopcounter int, @test varchar(100),
        @test2 varchar(100), @check int
set @maxloopcounter =  (select count(TableName) from #test)

while @LoopCounter <= @maxloopcounter
begin
    DECLARE @PropIDs TABLE (tablename varchar(max), id int )

    Insert into @PropIDs (tablename, id) 
    SELECT [tableName], id FROM #test  
    where id = @LoopCounter 

    set @test2 = (select columnname from #test where id = @LoopCounter)

    declare @sss varchar(max)
    set @sss = (select tablename from @PropIDs where id = @LoopCounter)

    set @check = (select count(@test2) 
                  from (select tablename 
                        from @PropIDs 
                        where id = @LoopCounter) A
                 )

    print @test2
    print @sss
    print @check

    set @LoopCounter = @LoopCounter + 1
end

为了在@Check=查询中使用变量作为列名和表名,您需要使用Dynamic SQL

There is most likely a better way to do this but I cant think of one off hand.很可能有更好的方法来做到这一点,但我想不出一个办法。 Here is what I would do.这就是我要做的。

  1. Use the select and declare a cursor rather than a while loop as you have it.使用 select 并声明一个游标,而不是像您拥有的 while 循环。 That way you dont have to count on sequential id's.这样你就不必依赖顺序 ID。 The cursor would fetch fields columnname, id and tablename游标将获取字段 columnname、id 和 tablename

  2. In the loop build a dynamic sql statement在循环中构建动态sql语句

    Set @Sql = 'Select Count(*) Cnt Into #Temp2 From ' + TableName + ' Where ' + @columnname + ' Is not null And ' + @columnname <> ''''' Set @Sql = 'Select Count(*) Cnt Into #Temp2 From ' + TableName + ' Where ' + @columnname + ' Is not null And ' + @columnname <> '''''

  3. Exec(@Sql)执行(@Sql)

  4. Then check #Temp2 for a value greater than 0 and if this is what you desire you can use the @id that was fetched to update your #Temp table.然后检查 #Temp2 是否有大于 0 的值,如果这是您想要的,您可以使用提取的 @id 来更新您的 #Temp 表。 Putting the result into a scalar variable rather than a temp table would be preferred but cant remember the best way to do that and using a temp table allows you to use an update join so it would well in my opinion.将结果放入标量变量而不是临时表将是首选,但不记得这样做的最佳方法,并且使用临时表允许您使用更新连接,因此在我看来这很好。

https://www.mssqltips.com/sqlservertip/1599/sql-server-cursor-example/ http://www.sommarskog.se/dynamic_sql.html https://www.mssqltips.com/sqlservertip/1599/sql-server-cursor-example/ http://www.sommarskog.se/dynamic_sql.html

Found a way to extract all non-empty tables from the schema, then just joined with the initial temp table that I had created.找到了一种从架构中提取所有非空表的方法,然后加入了我创建的初始临时表。

select A.tablename, B.[row_count]

from (select * from #test) A

left join

(SELECT r.table_name, r.row_count, r.[object_id]
FROM sys.tables t
INNER JOIN (
    SELECT OBJECT_NAME(s.[object_id]) table_name, SUM(s.row_count) row_count, s.[object_id]
    FROM sys.dm_db_partition_stats s
    WHERE s.index_id in (0,1)
    GROUP BY s.[object_id]
) r on t.[object_id] = r.[object_id]
WHERE r.row_count > 0 ) B
on A.[TableName] = B.[table_name]

WHERE ROW_COUNT > 0
order by b.row_count desc

How about this one - bitmask computed column checks for NULLability.这个一个如何 - 位掩码计算列检查可空性。 Value in the bitmask tells you if a column is NULL or not.位掩码中的值告诉您列是否为 NULL。 Counting base 2.计数基数 2。

    CREATE TABLE FindNullComputedMask
        (ID int
        ,val int
        ,valstr varchar(3)
        ,NotEmpty as 
            CASE WHEN ID IS NULL THEN 0 ELSE 1 END 
              | 
            CASE WHEN val IS NULL THEN 0 ELSE 2 END 
              | 
            CASE WHEN valstr IS NULL THEN 0 ELSE 4 END
        )

    INSERT FindNullComputedMask 
    SELECT 1,1,NULL

    INSERT FindNullComputedMask 
    SELECT NULL,2,NULL

    INSERT FindNullComputedMask 
    SELECT 2,NULL, NULL

    INSERT FindNullComputedMask
    SELECT 3,3,3

    SELECT *
    FROM FindNullComputedMask

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM