我正在尝试为许多可变销售中心提取每个月的销售业务数量。 使用以下TSQL ...
;WITH Months(m) AS
(
SELECT 1 m
UNION ALL
SELECT m+1 FROM Months WHERE m < 12
)
SELECT t.Center,m Month, t.Sales FROM Months
CROSS APPLY
(
SELECT C.Center, COUNT(1) Sales FROM Operations C
LEFT JOIN Centers A ON A.Code=C.Center
WHERE Date BETWEEN '01/'+ CONVERT(VARCHAR(2),Months.m) + '/2013' AND DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,'01/'+ CONVERT(VARCHAR(2),Months.m) + '/2013')+1,0))
GROUP BY C.Center
) t
所以我得到以下输出:
Center Month Sales
-----------------------
A 1 20
B 1 30
A 2 25
B 2 30
....
我想要结束的是:
Center 1 2 ...
----------------------
A 20 25 ...
B 30 30 ...
我正在研究使用xmlpath的数据透视图,但它太复杂了,我无法使其工作。有人有解决方案吗?
答案 0 :(得分:1)
也许我错过了你的问题,但由于一年只有12个月,所以没有理由使用动态SQL,因为你只有12列。
使用以下查询可以轻松完成此操作:
select center,
[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12]
from
(
select o.center, month(date) month
from operations o
inner join centers c
on o.center = c.code
where c.date >= '2013-01-01'
and c.date <= '2013-12-31'
) d
pivot
(
count(month)
for month in ([1], [2], [3], [4], [5], [6], [7], [8], [9],
[10], [11], [12])
) piv
如果您想动态执行此操作,则可以使用以下内容:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@startdate datetime,
@enddate datetime
set @startdate = '2013-01-01'
set @enddate = '2013-12-31'
;WITH Months(m) AS
(
SELECT 1 m
UNION ALL
SELECT m+1 FROM Months WHERE m < 12
)
select @cols = STUFF((SELECT ',' + QUOTENAME(m)
from Months
group by m
order by m
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT center, ' + @cols + '
from
(
select o.center, month(date) month
from operations o
inner join centers c
on o.center = c.code
where c.date >= '''+convert(varchar(10), @startdate, 120)+'''
and c.date <= '''+convert(varchar(10), @enddate, 120)+'''
) x
pivot
(
count(month)
for month in (' + @cols + ')
) p '
execute sp_executesql @query;
答案 1 :(得分:0)
不要这样做。为什么要将Sql Server打成不应该做的事情?
让您的查询垂直返回数据,就像您现在一样。
在应用程序级别转置它 编写,调试,维护和处理毫无疑问会出现的特殊业务规则会容易得多。
此外,它还可以更轻松地将数据粘贴到Excel中以进行故障排除和旋转。
答案 2 :(得分:0)
我终于实现了BlueFeet的第一个建议,稍作修改:
;WITH Months(m) AS
(
SELECT 1 m
UNION ALL
SELECT m+1 FROM Months WHERE m < 12
)
SELECT * FROM Months
CROSS APPLY
(
SELECT C.Center, COUNT(1) Sales FROM Operations C
LEFT JOIN Centers A ON A.Code=C.Center
WHERE Date BETWEEN '01/'+ CONVERT(VARCHAR(2),Months.m) + '/2013' AND DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,'01/'+ CONVERT(VARCHAR(2),Months.m) + '/2013')+1,0))
GROUP BY C.Center
) t
pivot
(
max(Sales)
for m in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])
) as PIV
我在寻找它不是在枢轴声明上写月份数字,所以我只能返回四分之一,例如。但这使得工作成为必需。 感谢。