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

时间:2012-09-27 16:15:00

标签: sql sql-server

我有一个约150列的表。我想为每一列找到count(distinct(colName)),但我想知道是否有办法在没有实际输入每个列名的情况下这样做。

理想情况下,我会使用count(distinct(*)),但这不起作用。

还有其他建议吗?

编辑:

如果这是我的桌子:

  id         col1         col2        col3      ...
  01         10001       west         north  
  02         10001       west         south  
  03         10002       east         south  
  04         10002       west         north  
  05         10001       east         south  
  06         10003       west         north 

我正在寻找此输出

count(distinct(id))   count(distinct(col1))    count(distinct(col2))   count(distinct(col3))
       6                       3                    2                      2

5 个答案:

答案 0 :(得分:5)

你可以这样做:

DECLARE @query varchar(max)
    SELECT @query = 
    'SELECT ' + SUBSTRING((SELECT ',' +'COUNT(DISTINCT(' + column_name + ')) 
             As ' + column_name + ' '  
             FROM information_schema.columns
             WHERE 
             table_name = 'table_name'
             for xml path('')),2,200000)  +  'FROM table_name'

PRINT(@query)

答案 1 :(得分:2)

使用以下脚本构建T-SQL查询,该查询将返回表中每列的不同计数。将@Table值替换为您的表名。

DECLARE @Table SYSNAME = 'TableName'; 

-- REVERSE and STUFF used to remove trailing UNION in string
SELECT REVERSE(STUFF(REVERSE((SELECT 'SELECT ''' + name 
                                     + ''' AS [Column], COUNT(DISTINCT(' 
                                     + QUOTENAME(name) + ')) AS [Count] FROM ' 
                                     + QUOTENAME(@Table) + ' UNION ' 
                              -- get column name from sys.columns  
                              FROM   sys.columns 
                              WHERE  object_id = Object_id(@Table)
                              -- concatenate result strings with FOR XML PATH
                              FOR XML PATH (''))), 1, 7, ';'));

答案 2 :(得分:1)

布莱恩的答案得到了扩展。他的答案按字母顺序列出了字段 如果您有十几个字段,这没有问题。如果您有150个字段,如OP所述,则会将字段保存在表格的顺序中 我修改了他的查询,以便检查213列(供应商的)表,并希望发布以供将来参考。

DECLARE @Table SYSNAME = 'Your table name; without schema; no square brackets'; 

-- REVERSE and STUFF used to remove trailing UNION in string
SELECT REVERSE(STUFF(REVERSE((SELECT 'SELECT ' 
        + CAST(column_id AS VarChar(4)) + ' AS [column_id],' -- extra column
        + '''' + name 
        + ''' AS [Column], COUNT(DISTINCT(' 
        + QUOTENAME(name) + ')) AS [Count] FROM ' 
        + QUOTENAME(@Table) + ' UNION ' 
    -- get column name from sys.columns  
    FROM   sys.columns 
    WHERE  system_type_id NOT IN (34,240) AND object_id = Object_id(@Table) 
    ORDER BY column_id -- keeps columns in table order
    -- concatenate result strings with FOR XML PATH
    FOR XML PATH (''))), 1, 7, ';'));

我决定不编辑布莱恩的答案,因为人们常常不需要额外的栏目。
(如果你没有添加column_id列,则ORDER BY无效。我相信这是因为只有最外层的ORDER BY才能保证订购最终输出;我很乐意有一个msft参考确认这个)

编辑:将函数Count与字段类型一起使用Image and Geography会抛出错误 添加" system_type_id NOT IN(34,240)"。

答案 3 :(得分:0)

我不相信只有MySQL才有可能。 我认为你将不得不使用服务器端语言来获得你想要的结果。

使用“DESC TABLE”作为第一个查询,然后对每个“字段”行编译查询。


忽略这个错误的系统标记:)

答案 4 :(得分:-1)

这应该做:

select count(*) from (select distinct * from myTable) as t

这是SQL Fiddle测试。

create table Data
(
    Id int,
    Data varchar(50)
)

insert into Data 
select 1, 'ABC'
union all
select 1, 'ABC'

select count(*) 
from (select distinct * from Data) as t