我正在使用SQL Server 2014
。下面是一个名为Table1
的表的摘录:
ID Market Adult AdultAge 0-5 6-12 13-17
100 UK 1 50 0 0 0
105 UK 2 36 0 0 0
107 DE 1 65 0 1 0
110 FR 2 42 0 2 1
115 BE 1 18 1 0 0
第0-5、6-12和13-17列是年龄类别,其中包含儿童人数。
我需要将此表转换为以下格式并使用以下逻辑:
所以,这是我想要的最终输出:
ID Market Age Category
100 UK 50 Adult
105 UK 36 Adult
105 UK 34 Adult
107 DE 65 Adult
107 DE 9 Child
110 FR 42 Adult
110 FR 40 Adult
110 FR 9 Child
110 FR 9 Child
110 FR 15 Child
115 BE 18 Adult
115 BE 2.5 Child
我正在考虑使用一些CASE
语句来转换数据,但是对于如何实现这些数据我确实感到困惑。
任何帮助将不胜感激。
答案 0 :(得分:3)
您需要详细的unpivot
。一种方法是使用统计表创建多行,并使用cross apply
:
;WITH Tally (n) AS
(
-- 1000 rows
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(n)
)
SELECT t.id,t.market,q.*
FROM [Table1] t
outer apply
(
select t.adultage,'Adult' where adult>=1
union all
select adultage-2,'Adult' where adult=2
union all
select 2.5,'Child' from Tally where n<=[0-5]
union all
select 9,'Child' from Tally where n<=[6-12]
union all
select 15,'Child' from Tally where n<=[13-17]
)q(Age,Category)
答案 1 :(得分:1)
这有点复杂,但是数字表会有所帮助。您可以使用递归CTE(最多100个)轻松生成一个,或者您周围可能只有一个。
然后您需要取消透视并应用更多逻辑:
with numbers as (
select 1 as n
union all
select n + 1
from numbers
where n <= 10
)
select x.*
from table1 t1 cross apply
(select t1.ID, t1.Market, category,
(case when v.category = 'Adult' and n.n = 2 then v.age - 2
else v.age
end) as age
from (values (t1.AdultAge, 'Adult', t1.Adult),
(2.5, 'Child', t1.[0-5]),
(9, 'Child', t1.[6-12]),
(15, 'Child', t1.[13-17])
) v(age, category, cnt) join
numbers n
on n.n <= v.cnt
) x;
Here是db <>小提琴。