我正在使用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
语句来查询。在这种情况下我应该做些什么?有这么聪明的方法吗?
答案 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表存储在临时表中。检查这是否会改善性能。