Sql 我如何做这个枢轴(转置)
在SQL Server中工作时,我有下表:Sql 我如何做这个枢轴(转置),sql,sql-server,pivot,Sql,Sql Server,Pivot,在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
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
访问温度处理denom num pct
A为了得到你想要的结果,你必须取消你的denom
、num
和pct
列,然后旋转治疗
。要取消打印列,您可以使用交叉应用
甚至取消打印
-这会将多个列转换为多行:
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)
看。然后应用轴:
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。动态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;
看。这两者都提供了:
| 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 |
|访问|温度|名称| 1 | 2|
|-------|-------------|-------|------|------|
|A |您真的希望输出中有500列吗?这会有意义吗,也就是说,人们真的会阅读所有500个专栏吗?通过有效地引用查询的性能,还是不必写出列,例如,PIVOT(在([1]、[2]、[3]、…[n]中处理的最大值)作为pvt
-如果只有3种治疗方法,那么应该只有三列?不知道你可以使用交叉应用到UNPIVOT…显然,正如我从SQL小提琴中看到的那样。你没有使用UNPIVOT有什么原因吗?使用交叉应用而不是UNPIVOT有什么好处吗?@TT。在这一点上,使用交叉应用是一种习惯因为当您必须成对取消PIVOT列时,取消PIVOT要容易得多。另外,如果您有不同的数据类型,您可以轻松地在交叉应用中转换/强制转换它们,而不必使用子查询,但正如您所看到的,取消PIVOT的工作原理是相同的——哦,取消PIVOT示例中的小错误:必须是unpivot(val表示名称in(denom,num,pct))
@TT.Yup,看看我为什么喜欢交叉应用-修复了我上面的评论和链接
| 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 |