我正在尝试将ID的某些字段移动到列中,但它似乎与我找到的所有数据透视示例不匹配。我可以找到的所有示例都使用某种形式的字段值分组。无论字段中的值如何,我都想使用更多的展示位置。我想在查询中执行此操作而不通过代码循环。
数据源示例(抱歉无法弄清楚如何在帖子上格式化表格,所以我使用了代码片段):
+----+--------+--------+
| ID | Field1 | Field2 |
+----+--------+--------+
| 1 | NULL | NULL |
| 2 | Jim | 321 |
| 2 | Jack | 54 |
| 2 | Sue | 985 |
| 2 | Gary | 654 |
| 3 | Herb | 332 |
| 3 | Chevy | 10 |
+----+--------+--------+
结果集我正在尝试生成:
+----+------+------+-------+------+------+------+
| ID | Col1 | Col2 | Col3 | Col4 | Col5 | Col6 |
+----+------+------+-------+------+------+------+
| 1 | NULL | NULL | | | | |
| 2 | Jim | 321 | Jack | 54 | Sue | 985 |
| 3 | Herb | 332 | Chevy | 10 | | |
+----+------+------+-------+------+------+------+
答案 0 :(得分:0)
SQL小提琴:http://sqlfiddle.com/#!3/a225a/1
;with cte as (
select id
, field1
, field2
, ROW_NUMBER() over (partition by id order by field1, field2) r
from @t
)
select c1.id
, c1.field1 col1
, c1.field2 col2
, c2.field1 col3
, c2.field2 col4
, c3.field1 col5
, c3.field2 col6
from cte c1
left outer join cte c2 on c2.id = c1.id and c2.r = c1.r + 1
left outer join cte c3 on c3.id = c1.id and c3.r = c1.r + 2
where (c1.r % 3) = 1
<强>解释强>
ROW_NUMBER() over (partition by id order by field1, field2) r
。此行确保每个id
的列数从1开始计算。这允许我们区分多行。
CTE
用于保存为c1
,c2
和c3
输入相同的语句。
连接确保行中的所有项具有相同的id,并且col1,col3和col5(同样为col2,col4和col6)的数据取自连续的行。我们正在使用left outer
联接,因为这些列的源表中可能没有行。
where
语句表示将每组3的第一行用于c1
中的数据(c2
和c3
因此是第二和第三行每集,感谢先前的加入)。
答案 1 :(得分:0)
这是一个使用动态sql的解决方案,虽然我确信有更好的方法。小心,这有点痛苦。首先,它构建要透视和选择的列列表,构建动态sql并运行它。
DECLARE @PivotColumns as varchar(max), @SelectColumns as varchar(max), @sql as varchar(max)
SELECT @PivotColumns = ISNULL(@PivotColumns + ',', '') + ColNum,
@SelectColumns = ISNULL(@SelectColumns + ',', '') + 'NULLIF(' + ColNum + ', ''NULL'') as ' + ColNum
from (select distinct 'Col' + cast(ROW_NUMBER() OVER (partition by id order by id) as varchar) as ColNum
from (select id,
isnull(field1,'NULL') as field1,
isnull(field2,'NULL') as field2
from weirdpivot) cols
unpivot
(
value
for col in (field1, field2)
) unpivoted) DistinctColumns
set @sql = '
select id, + ' + @SelectColumns + '
from (select
''Col'' + cast(ROW_NUMBER() OVER (partition by id order by id) as varchar) as colnum
,id
,value
from (select id,
isnull(field1,''NULL'') as field1,
isnull(field2,''NULL'') as field2
from weirdpivot) cols
unpivot
(
value
for col in (field1, field2)
) u) unpivoted
pivot
(
max(value)
for colnum in (' + @PivotColumns + ')
) p'
exec (@sql)