首页 > 解决方案 > 查询表中每列的填充行数(SQL Server)

问题描述

我正在尝试获取表中每一列的非空值计数。我研究了以下以前提出的 SO 问题,但没有找到满意的答案:

查询以列出数据库中每个表中的记录数

从表 SQL Server 中的每一列中获取每个值的计数

SQL Server 计算表每列中不同值的数量

我编写了以下代码来尝试为我的表构建一个数据字典,以包含列的名称、每列中填充的行数、数据类型、长度以及它是否是主键:

SELECT 
    c.name 'Column Name',
    p.rows 'Row_Count',
    t.Name 'Data type',
    c.max_length 'Max Length',
    ISNULL(i.is_primary_key, 0) 'Primary Key'
FROM    
    sys.columns c
INNER JOIN 
    sys.types t ON c.user_type_id = t.user_type_id
LEFT OUTER JOIN 
    sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
LEFT OUTER JOIN 
    sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
LEFT OUTER JOIN
sys.partitions p ON p.OBJECT_ID = i.OBJECT_ID and i.index_id = p.index_id
WHERE
    c.object_id = OBJECT_ID('my_table')

但是,Row_Count 列返回所有 Null。

我的预期结果如下所示:

Column_Name Row_Count Data_Type Max_Length Primary_Key
A              10       varchar   50            0
B              10       varchar   50            0
C              7        float     50            0
D              3        float     50            0
E              10       varchar   50            0

标签: sqlsql-servertsql

解决方案


这是一个不使用动态 SQL 的选项。

完全披露,我怀疑 DS 会更好。也就是说,这几乎适用于任何表、视图或查询。我master..spt_values用作演示

例子

Select ColumnName      = Item
      ,B.column_ordinal
      ,Row_Count       = sum(1)
      ,B.system_type_name
      ,B.max_length
      ,Distinct_Values = count(DISTINCT Value)
 From  (
        Select C.*
         From  master..spt_values A
         Cross Apply ( values (cast((Select A.* for XML RAW) as xml))) B(XMLData)
         Cross Apply (
                        Select Item  = replace(xAttr.value('local-name(.)', 'varchar(100)'),'_x0020_',' ')
                              ,Value = xAttr.value('.','varchar(max)')
                         From  XMLData.nodes('//@*') xNode(xAttr)
                     ) C
       ) A
 Left Join  (
        Select * from sys.dm_exec_describe_first_result_set('Select * from master..spt_values',null,null )  
       ) B on A.Item=B.name
 Group By A.Item
         ,B.system_type_name
         ,B.max_length
         ,B.column_ordinal 
 Order By B.column_ordinal 

退货

在此处输入图像描述

编辑

正如 Larnu 提到的,这将因 (var)binary 和 image 而失败。同样,这在大桌子上表现不佳。我只在发现阶段使用过这种方法。


推荐阅读