Jam*_*ith -1 sql pivot sql-server-2005
我正在尝试创建一个SQL语句,将可变数量的行(最多5个)转换为单行.一小部分数据如下所示:
+--------------+--------+-------+-------+
| ID | ItemID | Style | Qty |
+--------------+--------+-------+-------+
| 00001-5A-2XL | F911-5 | F911 | 1.566 |
| 00001-5A-2XL | 233-5 | 233 | 0.236 |
| 00001-5A-3XL | F911-5 | F911 | 1.697 |
| 00001-5A-3XL | 233-5 | 233 | 0.237 |
| 00001-5A-4XL | F911-5 | F911 | 1.833 |
| 00001-5A-4XL | 233-5 | 233 | 0.239 |
| 00001-5A-L | F911-5 | F911 | 1.307 |
| 00001-5A-L | 233-5 | 233 | 0.234 |
+--------------+--------+-------+-------+
Run Code Online (Sandbox Code Playgroud)
我想将数据转换为如下所示:
+--------------+------+--------+-----+--------+----+--------+----+--------+----+--------+
| ID | S1 | S1_Qty | S2 | S2_Qty | S3 | S3_Qty | S4 | S4_Qty | S5 | S5_Qty |
+--------------+------+--------+-----+--------+----+--------+----+--------+----+--------+
| 00001-5A-2XL | F911 | 1.566 | 233 | 0.236 | | | | | | |
| 00001-5A-3XL | F911 | 1.566 | 233 | 0.237 | | | | | | |
| 00001-5A-4XL | F911 | 1.566 | 233 | 0.239 | | | | | | |
| 00001-5A-L | F911 | 1.566 | 233 | 0.234 | | | | | | |
+--------------+------+--------+-----+--------+----+--------+----+--------+----+--------+
Run Code Online (Sandbox Code Playgroud)
我有点失去了当谈到旋转,特别是当我想转动两个Style和Quantity到我的专栏.我最多有5个样式(行)需要翻译成最多5列.
任何建议,指针等将不胜感激.
根据您的需要,您可以通过几种不同的方式获得结果.
如果您需要使用两个不同的聚合来获得结果,则不是很清楚.如果需要可能sum(qty)再使用max()的style,我会建议使用带有CASE表达式中的聚合函数来得到结果:
select id,
max(case when ItemID = 'F911-5' then Style end) Style1,
sum(case when ItemID = 'F911-5' then Qty else 0 end) Qty1,
max(case when ItemID = '233-5' then Style end) Style2,
sum(case when ItemID = '233-5' then Qty else 0 end) Qty2
from yourtable
group by id;
Run Code Online (Sandbox Code Playgroud)
请参阅SQL Fiddle with Demo.然后,当您有新ItemId值时,您将只添加新列.
你也可以使用PIVOT函数,但由于你需要在两列上进行PIVOT,我首先要先删除style和Qty列.这会将您的多列数据转换为多行,您可以使用UNPIVOT函数或CROSS APPLY获取结果 - 基本语法将是:
select id,
col = col+cast(seq as varchar(10)), value
from
(
select id, itemid, style, qty,
row_number() over(partition by id
order by qty desc) seq
from yourtable
) src
cross apply
(
select 'style', style union all
select 'qty', cast(qty as varchar(10))
) c(col, value)
Run Code Online (Sandbox Code Playgroud)
请参阅SQL Fiddle with Demo.这会将您的数据转换为多行,然后可以进行旋转:
| ID | COL | VALUE |
|--------------|--------|---------|
| 00001-5A-2XL | style1 | F911 |
| 00001-5A-2XL | qty1 | 1.56600 |
| 00001-5A-2XL | style2 | 233 |
| 00001-5A-2XL | qty2 | 0.23600 |
| 00001-5A-3XL | style1 | F911 |
Run Code Online (Sandbox Code Playgroud)
然后您可以应用PIVOT函数来获得最终结果:
select id, style1, qty1, style2, qty2
from
(
select id,
col = col+cast(seq as varchar(10)), value
from
(
select id, itemid, style, qty,
row_number() over(partition by id
order by qty desc) seq
from yourtable
) src
cross apply
(
select 'style', style union all
select 'qty', cast(qty as varchar(10))
) c(col, value)
) d
pivot
(
max(value)
for col in (style1, qty1, style2, qty2)
) piv;
Run Code Online (Sandbox Code Playgroud)
请参阅SQL Fiddle with Demo.最后,如果您有未知数量的值,则可以使用动态SQL来获取结果:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(col+cast(seq as varchar(10)))
from
(
select row_number() over(partition by id
order by qty desc) seq
from yourtable
) t
cross apply
(
select 'style', 1 union all
select 'qty', 2
) c (col, so)
group by col, so, seq
order by seq, so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT id, ' + @cols + '
from
(
select id,
col = col+cast(seq as varchar(10)), value
from
(
select id, itemid, style, qty,
row_number() over(partition by id
order by qty desc) seq
from yourtable
) src
cross apply
(
select ''style'', style union all
select ''qty'', cast(qty as varchar(10))
) c(col, value)
) x
pivot
(
max(value)
for col in (' + @cols + ')
) p '
execute sp_executesql @query;
Run Code Online (Sandbox Code Playgroud)
请参阅SQL Fiddle with Demo.结果如下:
| ID | STYLE1 | QTY1 | STYLE2 | QTY2 |
|--------------|--------|---------|--------|---------|
| 00001-5A-2XL | F911 | 1.56600 | 233 | 0.23600 |
| 00001-5A-3XL | F911 | 1.69700 | 233 | 0.23700 |
| 00001-5A-4XL | F911 | 1.83300 | 233 | 0.23900 |
| 00001-5A-L | F911 | 1.30700 | 233 | 0.23400 |
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
78 次 |
| 最近记录: |