在不同列上划分不同的值

时间:2014-11-20 13:25:22

标签: sql sql-server tsql case distinct

我正在使用SQL Server。我有下表(MyTable):

ID (int)
value (varchar)

我有以下查询:

select distinct value
from MyTable 

输出是:

Value_1
Value_2
Value_3
...
...
...
Value_450

我想创建下表(当value ='value_1'然后是1,否则o ...):

ID | Value_1 | Value_2 | Value_3 | Value_4 | .... | Value_450
1  |   0     |    1    |    0    |   0     | .... |   0
2  |   0     |    0    |    0    |   1     | .... |   0
3  |   1     |    0    |    0    |   0     | .... |   0
4  |   0     |    1    |    0    |   0     | .... |   0
5  |   0     |    0    |    0    |   0     | .... |   1
6  |   1     |    0    |    0    |   0     | .... |   0
7  |   0     |    0    |    0    |   1     | .... |   0
8  |   0     |    0    |    0    |   0     | .... |   1

如果value的不同值很小,我会使用Case语句来查询。在这种情况下我应该做些什么?有这么聪明的方法吗?

1 个答案:

答案 0 :(得分:1)

可以使用动态sql

完成
declare @query varchar(max);
declare @values varchar(max) = null;

with distinctValues as
(
    select distinct cast(value as varchar(20)) as value from myTable
)
select @values = COALESCE(@values + ', ['+ value + ']', '['+ value + ']') 
from distinctValues;

set @query = 'select [id], ' + @values +
'from myTable pivot ( count(value) for value in (' + @values + ')) as pvt';

exec(@query);

从评论中回答您的其他问题:

您可以使用INSERT ... EXEC语法将动态查询的结果插入表中:

insert into myOtherTable 
/* specify columns here if result does not have the same structure as the table */
exec(@query);

您说您有多个(6)列与您示例中的value列具有相同的角色。我假设列的名称是已知的并且不会改变。所以表结构是:

id, value1, value2, value3, value4, value5, value6

根据我的理解,结果必须如下:

id, v1, v2, v3, ..., vn

其中v1, v2, v3, ..., vn是可在列value1, value2, value3, value4, value5, value6

上找到的所有不同值

在这种情况下,您必须先使用UNPIVOT

declare @query varchar(max);
declare @values varchar(max) = null;

with distinctValues as
(
    select distinct cast(value as varchar(20)) as value 
    from myTable
    UNPIVOT
    (
       value for col in (value1, value2, value3, value4, value5, value6)
    ) as upvt
)
select @values = COALESCE(@values + ', ['+ value + ']', '['+ value + ']') 
from distinctValues;



set @query = 
';with myTableUnpivoted as 
( 
   select id, value 
   from myTable 
   UNPIVOT 
   ( 
      value for col in (value1, value2, value3, value4, value5, value6) 
   ) as upvt 
) 
select [id], ' + @values +
'from myTableUnpivoted pivot ( count(value) for value in (' + @values + ')) as pvt';

-- insert into myOtherTable
exec(@query);

请注意,UNPIVOT操作已完成两次。

您可以将unpivoted表存储在临时表中。检查这是否会改善性能。