在SQL-Server中工作,我有下表:
visit temperature treatment denom num pct
A <38°C 1 101 98 97.0
A 38.0-38.4°C 1 103 2 1.9
A 38.5-38.9°C 1 100 1 1.0
A <38°C 2 100 97 97.0
A 38.0-38.4°C 2 100 1 1.0
A 38.5-38.9°C 2 102 4 3.9
B <38°C 1 101 89 88.1
B 38.0-38.4°C 1 100 2 2.0
B 38.5-38.9°C 1 105 1 1.0
B <38°C 2 104 96 96.4
B 38.0-38.4°C 2 104 5 1.8
B 38.5-38.9°C 2 100 3 3.0
如何使表格看起来像这样?:
visit temperature name _1 _2
A <38°C denom 101.0 100.0
A <38°C num 98.0 97.0
A <38°C pct 97.0 97.0
A 38.0-38.4°C denom 103.0 100.0
A 38.0-38.4°C num 2.0 1.0
A 38.0-38.4°C pct 1.9 1.0
A 38.5-38.9°C denom 100.0 102.0
A 38.5-38.9°C num 1.0 4.0
A 38.5-38.9°C pct 1.0 3.9
B <38°C denom 101.0 104.0
B <38°C num 89.0 96.0
B <38°C pct 88.1 96.4
B 38.0-38.4°C denom 100.0 104.0
B 38.0-38.4°C num 2.0 5.0
B 38.0-38.4°C pct 2.0 1.8
B 38.5-38.9°C denom 105.0 100.0
B 38.5-38.9°C num 1.0 3.0
B 38.5-38.9°C pct 1.0 3.0
其中数字列中的_n是治疗出现的,对于某些访问可能有500次治疗,如何有效地处理,而不必将_1作为第一个旋转列,_2作为第二个旋转列,... ,_n作为最后一个旋转列?
由于
答案 0 :(得分:6)
为了获得您想要的结果,您将不得不取消忽略denom
,num
和pct
列,然后转动treatments
。要取消显示列,您可以使用CROSS APPLY
甚至UNPIVOT
- 这会将这些多列转换为多行:
select t.visit, t.temperature, t.treatment,
name,
val
from yourtable t
cross apply
(
select 'denom', denom union all
select 'num', num union all
select 'pct', pct
) c (name, val)
见Demo。然后你应用PIVOT:
select visit, temperature, name, [1], [2]
from
(
select t.visit, t.temperature, t.treatment,
name,
val
from yourtable t
cross apply
(
select 'denom', denom union all
select 'num', num union all
select 'pct', pct
) c (name, val)
) d
pivot
(
max(val)
for treatment in ([1], [2])
)piv;
见SQL Fiddle with Demo。现在上面的代码要求你写出所有的treatment
,如果你有一个未知的数字,那么你需要使用动态SQL。动态SQL创建一个然后执行的字符串:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(treatment)
from yourtable
group by treatment
order by treatment
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT visit, temperature, name,' + @cols + '
from
(
select t.visit, t.temperature, t.treatment,
name,
val
from yourtable t
cross apply
(
select ''denom'', denom union all
select ''num'', num union all
select ''pct'', pct
) c (name, val)
) x
pivot
(
max(val)
for treatment in (' + @cols + ')
) p '
exec sp_executesql @query;
见SQL Fiddle with Demo。这些都给出了:
| visit | temperature | name | 1 | 2 |
|-------|-------------|-------|------|------|
| A | <38°C | denom | 101 | 100 |
| A | <38°C | num | 98 | 97 |
| A | <38°C | pct | 97 | 97 |
| A | 38.0-38.4°C | denom | 103 | 100 |
| A | 38.0-38.4°C | num | 2 | 1 |
| A | 38.0-38.4°C | pct | 1.9 | 1 |
| A | 38.5-38.9°C | denom | 100 | 102 |
| A | 38.5-38.9°C | num | 1 | 4 |
| A | 38.5-38.9°C | pct | 1 | 3.9 |
| B | <38°C | denom | 101 | 104 |
| B | <38°C | num | 89 | 96 |
| B | <38°C | pct | 88.1 | 96.4 |
| B | 38.0-38.4°C | denom | 100 | 104 |
| B | 38.0-38.4°C | num | 2 | 5 |
| B | 38.0-38.4°C | pct | 2 | 1.8 |
| B | 38.5-38.9°C | denom | 105 | 100 |
| B | 38.5-38.9°C | num | 1 | 3 |
| B | 38.5-38.9°C | pct | 1 | 3 |