Sql 将列旋转为行,同时将行旋转为列。(SSMS)
我有下表…我们称之为表1Sql 将列旋转为行,同时将行旋转为列。(SSMS),sql,sql-server,pivot,Sql,Sql Server,Pivot,我有下表…我们称之为表1 TERM PERIOD Average StandardDeviation Minimum + 1 Period 2012Q3 0.00417 0.00722 0 + 120 Periods 2012Q3 0.02951 0.0014 0.028615 + 20 Periods 2012Q3 0.009898 0.0037
TERM PERIOD Average StandardDeviation Minimum
+ 1 Period 2012Q3 0.00417 0.00722 0
+ 120 Periods 2012Q3 0.02951 0.0014 0.028615
+ 20 Periods 2012Q3 0.009898 0.0037 0.007612
+ 40 Periods 2012Q3 0.018255 0.00262 0.016565
+ 1 Period 2012Q4 0.005 0.007 0
+ 120 Periods 2012Q4 0.026 0.001 0.03
+ 20 Periods 2012Q4 0.007 0.003 0.0042
+ 40 Periods 2012Q4 0.018 0.002 0.0165
有没有一种方法可以对其进行编码,这样我就可以得到一个如下所示的表:
TERM PATHS 2012Q3 2012Q4
+ 1 Period Average 0.00417 0.005
+ 1 Period StandardDeviation 0.00722 0.007
+ 1 Period Minimum 0 0
…依此类推,每项(+120个周期,+40个周期等)。要生成此结果,您需要同时使用和函数。
UNPIVOT
将列平均值
、标准偏差
和最小值
转换为多行。有了这些行后,就可以将透视
应用于期间
值。您的代码与此类似:
select term, paths,[2012Q3], [2012Q4]
from
(
select term, period, paths, value
from
(
select term, period, Average, StandardDeviation, Minimum
from table1
) s
unpivot
(
value
for paths in (Average, StandardDeviation, Minimum)
) unpiv
) src
pivot
(
max(value)
for period in ([2012Q3], [2012Q4])
) piv
看
这也可以通过使用UNION ALL
来取消pivot数据,使用带有CASE
表达式的聚合函数来透视:
select term,
paths,
max(case when period = '2012Q3' then value end) [2012Q3],
max(case when period = '2012Q4' then value end) [2012Q4]
from
(
select term, period, 'Average' Paths, average value
from Table1
union all
select term, period, 'StandardDeviation' Paths, StandardDeviation
from Table1
union all
select term, period, 'Minimum' Paths, Minimum
from Table1
) src
group by term, paths
看
如果您有已知数量的period
值,则上述版本非常有效。如果没有,则需要使用动态sql生成结果:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(PERIOD)
from Table1
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query
= 'select term, paths, '+@cols+'
from
(
select term, period, paths, value
from
(
select term, period, Average, StandardDeviation, Minimum
from table1
) s
unpivot
(
value
for paths in (Average, StandardDeviation, Minimum)
) unpiv
) p
pivot
(
max(value)
for period in('+@cols+')
) piv'
execute(@query)
看
所有版本都会产生相同的结果。要产生此结果,您需要同时使用和函数。
UNPIVOT
将列平均值
、标准偏差
和最小值
转换为多行。有了这些行后,就可以将透视
应用于期间
值。您的代码与此类似:
select term, paths,[2012Q3], [2012Q4]
from
(
select term, period, paths, value
from
(
select term, period, Average, StandardDeviation, Minimum
from table1
) s
unpivot
(
value
for paths in (Average, StandardDeviation, Minimum)
) unpiv
) src
pivot
(
max(value)
for period in ([2012Q3], [2012Q4])
) piv
看
这也可以通过使用UNION ALL
来取消pivot数据,使用带有CASE
表达式的聚合函数来透视:
select term,
paths,
max(case when period = '2012Q3' then value end) [2012Q3],
max(case when period = '2012Q4' then value end) [2012Q4]
from
(
select term, period, 'Average' Paths, average value
from Table1
union all
select term, period, 'StandardDeviation' Paths, StandardDeviation
from Table1
union all
select term, period, 'Minimum' Paths, Minimum
from Table1
) src
group by term, paths
看
如果您有已知数量的period
值,则上述版本非常有效。如果没有,则需要使用动态sql生成结果:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(PERIOD)
from Table1
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query
= 'select term, paths, '+@cols+'
from
(
select term, period, paths, value
from
(
select term, period, Average, StandardDeviation, Minimum
from table1
) s
unpivot
(
value
for paths in (Average, StandardDeviation, Minimum)
) unpiv
) p
pivot
(
max(value)
for period in('+@cols+')
) piv'
execute(@query)
看
所有版本都会产生相同的结果。我将其视为聚合和连接
select term, paths,
MIN(case when period = '2012Q3'
then (case when which = 'Average' then t.average
when which = 'StandardDeviation' then t.StandardDeviation
when which = 'Minimum' then t.Minimum
end)
end) as "2012Q3",
MIN(case when period = '2012Q4'
then (case when which = 'Average' then t.average
when which = 'StandardDeviation' then t.StandardDeviation
when which = 'Minimum' then t.Minimum
end)
end) as "2012Q4"
from Table1 t cross join
(select 'Average' as paths union all
select 'StandardDeviation' union all
select 'Minimum'
) const
group by term, paths
我将其视为聚合和连接
select term, paths,
MIN(case when period = '2012Q3'
then (case when which = 'Average' then t.average
when which = 'StandardDeviation' then t.StandardDeviation
when which = 'Minimum' then t.Minimum
end)
end) as "2012Q3",
MIN(case when period = '2012Q4'
then (case when which = 'Average' then t.average
when which = 'StandardDeviation' then t.StandardDeviation
when which = 'Minimum' then t.Minimum
end)
end) as "2012Q4"
from Table1 t cross join
(select 'Average' as paths union all
select 'StandardDeviation' union all
select 'Minimum'
) const
group by term, paths
谢谢很好用。@Kristina不客气,很乐意帮忙。:)是的,当我有一大堆专栏文章时,我总是尝试使用动态SQL!很好用。@Kristina不客气,很乐意帮忙。:)是的,当我有一大堆列时,我总是尝试使用动态SQL