我有这样的数据:
Product Group Product Level Quatity Sold Trend
==============================================================
Group 1 L1 10 up
Group 1 L2 20 up
Group 1 L3 30 down
Group 2 L1 20 up
Group 2 L2 40 up
Group 2 L3 60 down
Group 2 L4 80 down
我需要以这种格式获取数据:
Product Group L1 L1Trend L2 L2Trend L3 L3Trend L4 L4Trend
======================================================================================
Group 1 10 up 20 up 30 down
Group 2 20 up 40 up 60 down 80 down
我可以通过使用类似的东西来转向“产品级别”
PIVOT (MAX(quatity) FOR productlevel IN([L1],[L2],[L3],[L4]) AS p
但在处理趋势时迷失了方法。
感谢。
答案 0 :(得分:3)
您可以通过实施PIVOT功能获得所需的结果,但我会首先将您的多列Quantity Sold
和Trend
取消。 unpivot进程将它们从多列转换为多行数据。
由于您使用的是SQL Server 2008+,因此可以CROSS APPLY
使用VALUES
来取消数据的转出:
select [Product Group],
col, value
from yourtable
cross apply
(
values
([Product Level], cast([Quatity Sold] as varchar(10))),
([Product Level]+'trend', [trend])
) c (col, value);
请参阅SQL Fiddle with Demo这会将您的表数据转换为以下格式:
| PRODUCT GROUP | COL | VALUE |
|---------------|---------|-------|
| Group 1 | L1 | 10 |
| Group 1 | L1trend | up |
| Group 1 | L2 | 20 |
| Group 1 | L2trend | up |
| Group 1 | L3 | 30 |
| Group 1 | L3trend | down |
现在您可以轻松应用PIVOT功能:
select [Product Group],
L1, L1trend,
L2, L2trend,
L3, L3trend,
L4, L4trend
from
(
select [Product Group],
col, value
from yourtable
cross apply
(
values
([Product Level], cast([Quatity Sold] as varchar(10))),
([Product Level]+'trend', [trend])
) c (col, value)
) d
pivot
(
max(value)
for col in (L1, L1trend, L2, L2trend,
L3, L3trend, L4, L4trend)
) piv;
见SQL Fiddle with Demo。这样可以得到最终结果:
| PRODUCT GROUP | L1 | L1TREND | L2 | L2TREND | L3 | L3TREND | L4 | L4TREND |
|---------------|----|---------|----|---------|----|---------|--------|---------|
| Group 1 | 10 | up | 20 | up | 30 | down | (null) | (null) |
| Group 2 | 20 | up | 40 | up | 60 | down | 80 | down |
答案 1 :(得分:0)
您可以使用相关子查询来执行此操作:
select productGroup as [Product Group]
, (select sum(quantitySold) from myTable where productGroup = a.productGroup and productLevel = 'L1') as L1
, (select max(trend) from myTable where productGroup = a.productGroup and productLevel = 'L1') as L1Trend
, (select sum(quantitySold) from myTable where productGroup = a.productGroup and productLevel = 'L2') as L2
, (select max(trend) from myTable where productGroup = a.productGroup and productLevel = 'L2') as L2Trend
-- etc.
from myTable a
group by productGroup
order by productGroup
这是一个example SqlFiddle。
在您使用PIVOT
关键字之前,可以帮助您以这种方式查看。
如果你不知道你有多少个productLevel值,你需要一个动态的解决方案。
答案 2 :(得分:0)
如果你更喜欢使用数据透视,你可以试试这个:
select productgroup,
coalesce(L1up,L1down,'') L1, case when L1up is not null then 'up' when L1down is not null then 'down' else '' end L1trend,
coalesce(L2up,L2down,'') L2, case when L2up is not null then 'up' when L2down is not null then 'down' else '' end L2trend,
coalesce(L3up,L3down,'') L3, case when L3up is not null then 'up' when L3down is not null then 'down' else '' end L3trend,
coalesce(L4up,L4down,'') L4, case when L4up is not null then 'up' when L4down is not null then 'down' else '' end L4trend
from
(
select productgroup, [L1up],[L2up],[L3up],[L4up],[L1down],[L2down],[L3down],[L4down]
from (select productgroup, productlevel+trend pt, quantity from mytable) t
PIVOT (MAX(quantity)
FOR pt IN([L1up],[L2up],[L3up],[L4up],[L1down],[L2down],[L3down],[L4down] )) as p
) t