我对SQL很陌生,试图解决这个问题:
我有一个名为BUDGET的表,一年中每个月有12列,显示该月的预算余额。所以表格如下:
[Department] [Year] [Month1] [Month2] .... [Month12]
ABCD 2010 $5000 $5500 ..... $4000
ABCD 2011 $6000 $6500 ..... $3000
我要做的是规范化此表并将每行分成12行,每行使用以下格式的日期字段。我还希望有一个[Balance]列显示该月的值。因此,规范化表格如下所示:
[Department] [Date] [Balance]
ABCD 20100101 $5000
ABCD 20100201 $5500
ABCD 20100301 .....
ABCD ....... ......
我尝试在同一张桌子上使用CROSS JOIN但失败了。我也试过使用while循环,但也失败了。任何形式的帮助表示赞赏。谢谢!
编辑:我正在使用SQL Server 2008
答案 0 :(得分:10)
这里有一个十字架应用解决方案:
SELECT
B.Department,
DateAdd(month, (B.Year - 1900) * 12 + M.Mo - 1, 0) [Date],
M.Balance
FROM
dbo.Budget B
CROSS APPLY (
VALUES
(1, Month1), (2, Month2), (3, Month3), (4, Month4), (5, Month5), (6, Month6),
(7, Month7), (8, Month8), (9, Month9), (10, Month10), (11, Month11), (12, Month12)
) M (Mo, Balance);
与@Aaron Bertrand的UNPIVOT没有什么不同,没有使用UNPIVOT。
如果您必须将日期作为字符串,则将字符串放入CROSS APPLY中,如('01', Month1)
,并将SELECT更改为Convert(char(4), B.Year) + M.Mo
。
答案 1 :(得分:4)
SELECT
Department,
[Date] = DATEADD(MONTH, CONVERT(INT, SUBSTRING([Month],6,2))-1,
DATEADD(YEAR, [Year]-1900, 0)),
Balance
FROM
dbo.BUDGET AS b
UNPIVOT
(
Balance FOR [Month] IN
(
Month1, Month2, Month3, Month4,
Month5, Month6, Month7, Month8,
Month9, Month10, Month11, Month12
)
) AS y
ORDER BY Department, [Date];
答案 2 :(得分:1)
我就是这样做的。没有必要对它有所了解。
select department = b.department ,
year = b.year ,
month = m.month ,
balance = case m.month
when 1 then b.Month1
when 2 then b.Month2
when 3 then b.Month3
when 4 then b.Month4
when 5 then b.Month5
when 6 then b.Month6
when 7 then b.Month7
when 8 then b.Month8
when 9 then b.Month9
when 10 then b.Month10
when 11 then b.Month11
when 12 then b.Month12
else null
end
from dbo.budget b
join ( select month = 1
union all select month = 2
union all select month = 3
union all select month = 4
union all select month = 5
union all select month = 6
union all select month = 7
union all select month = 8
union all select month = 9
union all select month = 10
union all select month = 11
union all select month = 12
) m on 1 = 1 -- a dummy join: we want the cartesian product here so as to expand every row in budget into twelve, one per month of the year.