SQL从表
返回以下结果+-----+----+-----+----+----+
| PID | PY | QTY | TS | TM |
+-----+----+-----+----+----+
| 99 | CT | 1 | 1 | 6 |
| 99 | E | 3 | 1 | 5 |
| 99 | GR | 4 | 1 | 6 |
+-----+----+-----+----+----+
我想使用PIVOT(如果可能的话)来制作如下结果:
+-----+----+-----+----+----+----+------+------+------+------+------+------+------+
| PID | PY | QTY | TS | TM | PY | QTY | TS | TM | PY | QTY | TS | TM |
+-----+----+-----+----+----+----+------+------+------+------+------+------+------+
| 99 | CT | 1 | 1 | 6 | E | 3 | 1 | 5 | GR | 4 | 1 | 6 |
| 100 | V | 6 | 6 | 2 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
+-----+----+-----+----+----+----+------+------+------+------+------+------+------+
答案 0 :(得分:2)
如果您的值有限,那么获得结果的最简单方法是使用带有一些CASE表达式的聚合函数。
select
pid,
PY1 = max(case when py = 'CT' then PY end),
QTY1 = max(case when py = 'CT' then QTY else 0 end),
TS1 = max(case when py = 'CT' then TS else 0 end),
TM1 = max(case when py = 'CT' then TM else 0 end),
PY2 = max(case when py = 'E' then PY end),
QTY2 = max(case when py = 'E' then QTY else 0 end),
TS2 = max(case when py = 'E' then TS else 0 end),
TM2 = max(case when py = 'E' then TM else 0 end),
PY3 = max(case when py = 'GR' then PY end),
QTY3 = max(case when py = 'GR' then QTY else 0 end),
TS3 = max(case when py = 'GR' then TS else 0 end),
TM3 = max(case when py = 'GR' then TM else 0 end),
PY4 = max(case when py = 'V' then PY end),
QTY4 = max(case when py = 'V' then QTY else 0 end),
TS4 = max(case when py = 'V' then TS else 0 end),
TM4 = max(case when py = 'V' then TM else 0 end)
from yourtable
group by pid;
见SQL Fiddle with Demo。您可以使用PIVOT来获得结果,但它会更加混乱,因为您需要首先取消多列的转换,然后再转动它们。如果要使用pivot功能,则必须执行以下操作。
首先,使用row_number()
为每个pid
组合分配一个唯一值:
select pid, py, qty, ts, tm,
rn = row_number() over(partition by pid order by pid)
from yourtable
然后取消忽略多个列py
,qty
,ts
和tm
:
select
pid,
new_col = col + cast(rn as varchar(10)),
val
from
(
select pid, py, qty, ts, tm,
rn = row_number() over(partition by pid order by pid)
from yourtable
) d
cross apply
(
select 'py', py union all
select 'qty', cast(qty as varchar(10)) union all
select 'ts', cast(ts as varchar(10)) union all
select 'tm', cast(tm as varchar(10))
) c (col, val)
我使用CROSS APPLY
将多列转换为多行。最后,您将转动new_col
及其相应的值:
select pid,
py1, qty1, ts1, tm1, py2, qty2, ts2, tm2,
py3, qty3, ts3, tm3, py4, qty4, ts4, tm4
from
(
select
pid,
new_col = col + cast(rn as varchar(10)),
val
from
(
select pid, py, qty, ts, tm,
rn = row_number() over(partition by pid order by pid)
from yourtable
) d
cross apply
(
select 'py', py union all
select 'qty', cast(qty as varchar(10)) union all
select 'ts', cast(ts as varchar(10)) union all
select 'tm', cast(tm as varchar(10))
) c (col, val)
) src
pivot
(
max(val)
for new_col in (py1, qty1, ts1, tm1, py2, qty2, ts2, tm2,
py3, qty3, ts3, tm3, py4, qty4, ts4, tm4)
) piv;
两个版本都会给出相同的最终结果。
| pid | py1 | qty1 | ts1 | tm1 | py2 | qty2 | ts2 | tm2 | py3 | qty3 | ts3 | tm3 | py4 | qty4 | ts4 | tm4 |
|-----|-----|------|-----|-----|-----|------|-----|-----|-----|------|-----|-----|--------|--------|--------|--------|
| 99 | CT | 1 | 1 | 6 | E | 3 | 1 | 5 | GR | 4 | 1 | 6 | (null) | (null) | (null) | (null) |