1

我有一个大约 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
4

5 回答 5

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)
于 2012-09-27T16:29:26.947 回答
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, ';'));
于 2012-09-27T16:38:22.360 回答
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 参考来证实这一点)

编辑:对字段类型 Image 和 Geography 使用函数 Count 会引发错误。
添加了“system_type_id NOT IN (34,240)”。

于 2018-03-21T16:34:39.760 回答
0

我不相信只有 MySQL 是可能的。我认为您将不得不使用服务器端语言来获得所需的结果。

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


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

于 2012-09-27T16:19:12.907 回答
-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
于 2012-09-27T16:24:04.593 回答