显示表中所有列的计数和不同值

时间:2017-10-06 19:00:03

标签: sql

我有一个包含700列的表格。我正在尝试获取每列的不同值列表及其计数。我使用以下查询来获取1列的结果

Select distinct col1, count(*) from MyTable group by 1.

结果:

col1    count(*)
a       10
b       20
c       40

如何以最佳方式使用单个查询获取所有列的结果?

3 个答案:

答案 0 :(得分:1)

基本查询是:

select col001, count(*) from MyTable group by col001 union all
select col002, count(*) from MyTable group by col002 union all
. . . 
select col700, count(*) from MyTable group by col700 ;

不愉快,但这基本上是您需要运行的查询。与单独执行相比,SQL实际上并没有更有效地执行多个独立聚合(根据我的经验,甚至使用grouping sets。)

您可以构建查询。一种方法是运行这样的东西:

select replace(replace('select [col], count(*) as cnt from [tab] group by [col] union all ',
                       '[tab]', table_name
                      ), '[col]', column_name
               )
from information_schema.columns
where table_name = 'mytable' and table_schema = ??;

然后,您可以复制生成的SQL(删除最终的union all)并运行它。

注意:以上是通用的;确切的代码可能因数据库而异。

答案 1 :(得分:0)

不可能为每列提供具有不同值的列表。如果A列具有5个不同的值而B列具有7个值,该怎么办?

另一个问题比较容易,但是正如@Gordon Linoff指出的那样,需要两个步骤。针对MS SQL详细说明他的答案:

select replace(replace(' count(distinct([col])) as [col],',
                       '[tab]', table_name
                      ), '[col]', column_name
               )
from information_schema.columns
where table_name = 'your_table';

复制结果并将其粘贴到之间的新查询窗口中。

SELECT
[[results query 1]]
FROM your_table

记住要从查询1结果中删除最后一个','。

答案 2 :(得分:0)

用需要计数的表替换[表名]。

DECLARE @table varchar(100) = '[table name]'
DECLARE @i INT = 1, @cntOUT int, @SQL nvarchar(500) = ''
DECLARE @ParmDef nvarchar(500) = N'@cnt int OUTPUT'; 

SELECT column_id, name, 0 as record_count
INTO #T1  
FROM sys.all_columns c 
WHERE c.object_id = (SELECT object_id FROM sys.objects WHERE name = @table AND type = 'U')

WHILE @i <= (SELECT MAX(column_id) FROM #T1)
BEGIN
    SELECT @SQL = 'SELECT @cnt = COUNT(DISTINCT ' + name + ') FROM ' + @table + ';' 
    FROM #T1 WHERE column_id = @i;

    EXECUTE sp_executesql @stmt = @SQL, @ParmDefinition = @ParmDef, @cnt = @cntOUT OUTPUT;
    UPDATE #T1 SET record_count = @cntOUT WHERE column_id = @i
    SET @i = @i + 1
END

SELECT * FROM #T1
--DROP TABLE #T1