列出具有不同值的数量的所有列

时间:2014-08-06 14:44:04

标签: sql sql-server sql-server-2008

我希望得到一个包含两列的表格:

  • 一个包含表的每个列名称
  • 第二个包含存储在此列中的不同值的计数。

所以如果我有一个包含四列的表:

id boat fish    date
1  2    Brass   2014-08-03
2  3    Halibut 2014-08-03
3  2    Plaice  2014-08-04
4  1    Salmon  2014-08-04
5  3    Plaice  2014-08-04

结果表应该是

column count
id     5
boat   3
fish   4
date   2

id boat fish date
5  3    4    2

我试过了:

SELECT c.name AS column_name, (SELECT COUNT(DISTINCT [c.name]) FROM catches)
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE t.name LIKE '%catches%'

哪个不起作用,因为我不能使用c.name中的字符串作为列标识符。至少不是我尝试的方式。我可以,如果是,如何?

1 个答案:

答案 0 :(得分:2)

如果我理解,你可以使用计数区别:

select
count (distinct [id]) as IDs,
count (distinct boat)  as boats,
count (distinct fish) as fish,
count (distinct [date]) as dates
       from
       table1

返回:

IDS     BOATS   FISH    DATES
5       3       4       2

SQL Fiddle

编辑: 重新阅读您的问题后,如果您有大量列,或者您不想对列名进行硬编码,则可以使用游标来构建您的选择。我怀疑如果你足够努力,你可以建立一个枢轴来做同样的事情,但在这种特殊情况下,我认为光标是一个好的解决方案。 声明@SQL nvarchar(max)

set @SQL = 'SELECT '
DECLARE @Counter integer
set @Counter = 0
declare @colName nvarchar(100)



DECLARE cols CURSOR 
for
select
distinct sc.name as ColName
from
sys.tables  st
inner join sys.schemas ss
    on st.schema_id = st.schema_id
inner join sys.columns sc
    on st.object_id = sc.object_id
where
st.name = '<YourTable>'  
and ss.name = '<YourSchema>'

open cols
fetch next from cols into @colName


WHILE @@FETCH_STATUS = 0  
begin
    if (@counter = 0) 
        begin
            set @SQL = @SQL + 'COUNT(DISTINCT ' +@colName + ') AS ' + @colName + 's'
        end
    else
        begin
            set @SQL = @SQL + ',COUNT(DISTINCT ' +@colName + ') AS ' + @colName + 's'
        end
    set @Counter = @Counter + 1
    fetch next from cols into @colName
end

close cols
deallocate cols
set @SQL = @SQL + ' from <YourSchema>.<YourTable>'
print @SQL
EXECUTE sp_ExecuteSQL @SQL


WHILE @@FETCH_STATUS = 0  
begin
    if (@counter = 0) 
        begin
            set @SQL = @SQL + 'COUNT(DISTINCT ' +@colName + ') AS ' + @colName + 's'
        end
    else
        begin
            set @SQL = @SQL + ',COUNT(DISTINCT ' +@colName + ') AS ' + @colName + 's'
        end
    set @Counter = @Counter + 1
    fetch next from cols into @colName
end

close cols
deallocate cols
set @SQL = @SQL + ' from Auditing.T_RPT_DIM'
print @SQL
EXECUTE sp_ExecuteSQL @SQL