从表中的所有列中选择所有唯一值

时间:2018-04-13 12:46:21

标签: sql-server tsql dynamic-sql

我需要从表格中的所有列中选择所有唯一值。

我试图在线程How to get unique values from all columns of a table in SQL Server中找到下面的查询。

declare @Sql_Str varchar(8000)=''; 

select @Sql_Str=@Sql_Str+' select cast (' +name  +' as varchar(500)) 
                           from  <yourtable> union'
from sys.columns 
where [object_id]=object_id('<yourtable>'); 

set @Sql_Str=SUBSTRING(@Sql_Str,1,len(@Sql_Str)-6);
exec(@Sql_Str)

然而,我无法使该查询起作用。我的表有118列。我认为这可能比上面的查询可能处理的数据更多。

2 个答案:

答案 0 :(得分:0)

尝试这样的事情:

DECLARE @Schema VARCHAR(500)='dbo';
DECLARE @tableName VARCHAR(500)='SomeTable';

DECLARE @cmd NVARCHAR(MAX)=
(
    SELECT STUFF(
    (
            SELECT ' UNION ALL SELECT ''' + c.TABLE_SCHEMA + ''' AS TableSchema '
                 + ',''' + c.TABLE_NAME + ''' AS TableName '
                 + ',''' + c.COLUMN_NAME + ''' AS ColumnName '
                 + ',''' + c.DATA_TYPE + ''' AS ColumnType '
                 + ',CAST(' + QUOTENAME(c.COLUMN_NAME)+' AS NVARCHAR(MAX)) AS Value ' 
                 + ' FROM ' + QUOTENAME(c.TABLE_SCHEMA) + '.' + QUOTENAME(c.TABLE_NAME)
                 + ' WHERE ' + QUOTENAME(c.COLUMN_NAME) + ' IS NOT NULL ' 
                 + ' GROUP BY ' + QUOTENAME(c.COLUMN_NAME) + ' ' 
            FROM INFORMATION_SCHEMA.COLUMNS AS c
            WHERE TABLE_NAME=@TableName
              AND TABLE_SCHEMA=@Schema
              --exclude not supported types
              --AND c.DATA_TYPE NOT IN('xml') --add more types
            FOR XML PATH(''),TYPE
    ).value('.','nvarchar(max)'),1,10,'')
);
--PRINT @cmd
EXEC(@cmd);

此语句将首先创建一个UNION ALL SELECT的长列表,其中GROUP BY(优于DISTINCT)为动态创建的SQL,并使用EXEC()执行此操作。

您可以撤消PRINT以检查创建的语句。

答案 1 :(得分:0)

这应该在tSQL中起作用:

declare @table_name varchar(55)
set @table_name= 'IV00101' ---- <-- Change this to your table name
create table #colcount (
    colname varchar(55),
    dct int,
    tot int
)
create table #colContent (
    colname varchar(55),
    col_val nvarchar(max),
    col_val_count int
)
create table #sqlexecs( s varchar(max))
declare @col_name varchar(max), @sql nvarchar(max), @sql2 nvarchar(max)
declare c cursor for 
select name from sys.columns where [object_id]=object_id(@table_name)
open c
fetch next from c into @col_name

while @@FETCH_STATUS = 0
begin
    set @sql = 'select cn.name, count(distinct '+@col_name+') as dct_numrow, count('+@col_name+') as tot_numrow from '+@table_name+' join (select name from sys.columns where name = '''+@col_name+''' and [object_id]=object_id('''+@table_name+''')) cn on cn.name = '''+@col_name+''' group by cn.name'
    set @sql2 = 'select ' +@col_name+', count('+@col_name+') as colvalcnt from '+@table_name+' group by '+@col_name
    --insert into #sqlexecs values (@sql) --uncomment to  view sql selects produced by @sql
    --insert into #sqlexecs values (@sql2) --uncomment to  view sql selects produced by @sql2
    insert into #colcount execute sp_executesql @sql
    ------
    declare @d int, @t int
    set @d = (select dct from #colcount where colname = @col_name)
    set @t = (select tot from #colcount where colname = @col_name)
    if (@d <> @t) 
    begin
        insert into #colContent (colname) values (@col_name)
        insert into #colContent (col_val,col_val_count) execute sp_executesql @sql2
    end
    else
    begin
        insert into #colContent values (@col_name,1,1)
    end
    fetch next from c into @col_name
end
close c
deallocate c


--select * from #sqlexecs -- uncomment to view sql code produced by @sql and @sql2
select * from #colcount --order by dct desc
select * from #colContent

drop table #colcount
drop table #colContent
drop table #sqlexecs

第一张表显示列名,不同值计数和总值计数。
第二张表显示列名,不同的值以及不同的值出现的次数。如果列中的值都是不同的(列是候选键),则colname | 1 |显示了1。

如果复制/粘贴,这应该可以工作,请让我知道不能。用于Dynamics GP的开发。

相关问题