我目前有一个查询,其中列出了过去12个月的总销售额
SELECT
TOP 10 SUM(CustomerInvoice.Total) AS 'Total', CustomerName
FROM dbo.CustomerInvoice
INNER JOIN dbo.Customer
ON CustomerInvoice.BillToCode = Customer.CustomerCode
WHERE InvoiceDate BETWEEN CAST(dateadd(year, -1, getdate()) AS SMALLDATETIME) AND CAST(GETDATE() AS SMALLDATETIME)
GROUP BY CustomerName
ORDER BY Total DESC
这样会返回一个表。
╔═══════════╦═══════════════╗
║ Total ║ Customer Name ║
╠═══════════╬═══════════════╣
║ 806405.85 ║ Customer 1 ║
╠═══════════╬═══════════════╣
║ 128244.77 ║ Customer 2 ║
╠═══════════╬═══════════════╣
║ 80127.75 ║ Customer 3 ║
╠═══════════╬═══════════════╣
║ 71994.56 ║ Customer 4 ║
╠═══════════╬═══════════════╣
║ 67641.31 ║ Customer 5 ║
╠═══════════╬═══════════════╣
║ 67064.04 ║ Customer 6 ║
╠═══════════╬═══════════════╣
║ 60324.39 ║ Customer 7 ║
╠═══════════╬═══════════════╣
║ 59684.7 ║ Customer 8 ║
╠═══════════╬═══════════════╣
║ 59066.31 ║ Customer 9 ║
╠═══════════╬═══════════════╣
║ 57112.04 ║ Customer 10 ║
╚═══════════╩═══════════════╝
我需要的是每个客户的月销售额,表格格式如下:
╔═══════════════╦═════════╦═════════╦═════════╦═════════╦═════════╦═════════╦═════════╦═════════╦═════════╦═════════╦═════════╦═════════╗
║ ///////////// ║ Jul-15 ║ Aug-15 ║ Sep-15 ║ Oct-15 ║ Nov-15 ║ Dec-15 ║ Jan-16 ║ Feb-16 ║ Mar-16 ║ Apr-16 ║ May-16 ║ Jun-16 ║
╠═══════════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╣
║ Customer 1 ║ 2087.23 ║ 4289.49 ║ 2326.14 ║ 1058.48 ║ 552.03 ║ 2438.16 ║ 7146.80 ║ 9305.66 ║ 8800.45 ║ 7199.57 ║ 1247.92 ║ 8977.39 ║
╠═══════════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╣
║ Customer 2 ║ 36.28 ║ 9327.53 ║ 2385.92 ║ 9372.04 ║ 2877.75 ║ 543.23 ║ 5464.15 ║ 4426.06 ║ 93.84 ║ 843.24 ║ 6895.55 ║ 74.02 ║
╠═══════════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╣
║ Customer 3 ║ 9492.12 ║ 9285.28 ║ 4528.11 ║ 7198.50 ║ 4037.02 ║ 5160.75 ║ 8246.33 ║ 6806.81 ║ 7051.14 ║ 814.43 ║ 9631.44 ║ 804.93 ║
╠═══════════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╣
║ Customer 4 ║ 9217.58 ║ 9147.28 ║ 2202.67 ║ 6432.05 ║ 2365.12 ║ 4973.94 ║ 5486.00 ║ 1793.43 ║ 1284.91 ║ 3671.67 ║ 751.11 ║ 5483.26 ║
╠═══════════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╣
║ Customer 5 ║ 3211.68 ║ 3329.07 ║ 2319.50 ║ 5077.95 ║ 8977.03 ║ 6813.39 ║ 4890.97 ║ 345.05 ║ 483.89 ║ 565.10 ║ 7760.01 ║ 6465.55 ║
╠═══════════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╣
║ Customer 6 ║ 1683.52 ║ 4287.37 ║ 524.30 ║ 4595.54 ║ 1102.11 ║ 4623.11 ║ 3165.83 ║ 2363.13 ║ 2584.55 ║ 3420.01 ║ 9496.31 ║ 2940.19 ║
╠═══════════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╣
║ Customer 7 ║ 1325.93 ║ 1847.88 ║ 3107.79 ║ 1855.39 ║ 7698.80 ║ 5360.15 ║ 7752.69 ║ 8289.06 ║ 8444.03 ║ 2719.06 ║ 6187.75 ║ 4921.10 ║
╠═══════════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╣
║ Customer 8 ║ 7573.35 ║ 2198.58 ║ 3432.29 ║ 6427.38 ║ 3856.54 ║ 9164.15 ║ 4945.19 ║ 9812.18 ║ 4712.47 ║ 5530.55 ║ 2396.45 ║ 2914.75 ║
╠═══════════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╣
║ Customer 9 ║ 8278.74 ║ 4865.93 ║ 4071.40 ║ 5628.76 ║ 3202.43 ║ 7270.84 ║ 811.55 ║ 275.52 ║ 3451.58 ║ 8164.47 ║ 8117.53 ║ 66.86 ║
╠═══════════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╬═════════╣
║ Customer 10 ║ 581.96 ║ 8288.06 ║ 521.93 ║ 8938.67 ║ 3211.10 ║ 348.94 ║ 6841.85 ║ 3282.51 ║ 2007.62 ║ 1621.19 ║ 5982.00 ║ 3841.82 ║
╚═══════════════╩═════════╩═════════╩═════════╩═════════╩═════════╩═════════╩═════════╩═════════╩═════════╩═════════╩═════════╩═════════╝
我有这个查询,但有没有办法可以让查询动态选择过去12个月的列?
SELECT TOP 100 * FROM(
SELECT CustomerName
, SUM(CASE WHEN DATEPART(YEAR, InvoiceDate) = 2015 AND DATEPART(MONTH, InvoiceDate) = 8 THEN Total ELSE 0 END) AS [Aug-15]
, SUM(CASE WHEN DATEPART(YEAR, InvoiceDate) = 2015 AND DATEPART(MONTH, InvoiceDate) = 9 THEN Total ELSE 0 END) AS [Sep-15]
, SUM(CASE WHEN DATEPART(YEAR, InvoiceDate) = 2015 AND DATEPART(MONTH, InvoiceDate) = 10 THEN Total ELSE 0 END) AS [Oct-15]
, SUM(CASE WHEN DATEPART(YEAR, InvoiceDate) = 2015 AND DATEPART(MONTH, InvoiceDate) = 11 THEN Total ELSE 0 END) AS [Nov-15]
, SUM(CASE WHEN DATEPART(YEAR, InvoiceDate) = 2015 AND DATEPART(MONTH, InvoiceDate) = 12 THEN Total ELSE 0 END) AS [Dec-15]
, SUM(CASE WHEN DATEPART(YEAR, InvoiceDate) = 2016 AND DATEPART(MONTH, InvoiceDate) = 1 THEN Total ELSE 0 END) AS [Jan-16]
, SUM(CASE WHEN DATEPART(YEAR, InvoiceDate) = 2016 AND DATEPART(MONTH, InvoiceDate) = 2 THEN Total ELSE 0 END) AS [Feb-16]
, SUM(CASE WHEN DATEPART(YEAR, InvoiceDate) = 2016 AND DATEPART(MONTH, InvoiceDate) = 3 THEN Total ELSE 0 END) AS [Mar-16]
, SUM(CASE WHEN DATEPART(YEAR, InvoiceDate) = 2016 AND DATEPART(MONTH, InvoiceDate) = 4 THEN Total ELSE 0 END) AS [Apr-16]
, SUM(CASE WHEN DATEPART(YEAR, InvoiceDate) = 2016 AND DATEPART(MONTH, InvoiceDate) = 5 THEN Total ELSE 0 END) AS [May-16]
, SUM(CASE WHEN DATEPART(YEAR, InvoiceDate) = 2016 AND DATEPART(MONTH, InvoiceDate) = 6 THEN Total ELSE 0 END) AS [Jun-16]
, SUM(CASE WHEN DATEPART(YEAR, InvoiceDate) = 2016 AND DATEPART(MONTH, InvoiceDate) = 7 THEN Total ELSE 0 END) AS [Jul-16]
, SUM(CASE WHEN InvoiceDate BETWEEN CAST(dateadd(year, -1, getdate()) AS SMALLDATETIME) AND CAST(GETDATE() AS SMALLDATETIME) THEN CI.Total ELSE 0 END) AS 'Total'
FROM CustomerInvoice CI
JOIN Customer C ON CI.BillToCode = C.CustomerCode
GROUP BY C.CustomerName) A
ORDER BY Total DESC
答案 0 :(得分:1)
要生成列名,请创建一个如下变量:
DECLARE @cols VARCHAR(4000) = '';
SELECT @cols += '
, SUM(CASE WHEN DATEPART(YEAR, InvoiceDate) = ' + CAST(DATEPART(YEAR, DATEADD(MONTH, -number, GETDATE())) AS CHAR(4)) + ' AND DATEPART(MONTH, InvoiceDate) = ' + CAST(DATEPART(MONTH, DATEADD(MONTH, -number, GETDATE())) AS CHAR(4)) + ' THEN Total ELSE 0 END) AS ' + QUOTENAME(LEFT(DATENAME(MONTH, DATEADD(MONTH, -number, GETDATE())), 3) + '-' + RIGHT(DATEPART(YEAR, DATEADD(MONTH, -number, GETDATE())), 2))
FROM master..spt_values
WHERE number < 12
AND type = 'p'
ORDER BY number DESC;
--PRINT @cols;
这样做是生成要在动态SQL中使用的select语句的一部分。这是您的条件聚合。
然后你写出你的动态SQL并执行它,就像这样......
DECLARE @SQL NVARCHAR(MAX) = 'SELECT CustomerName' + @cols + '
FROM dbo.CustomerInvoice CI
JOIN dbo.Customer C ON CI.BillToCode = C.CustomerCode
WHERE InvoiceDate BETWEEN CAST(DATEADD(YEAR, -1, GETDATE()) AS SMALLDATETIME) AND CAST(GETDATE() AS SMALLDATETIME)
AND CustomerName IN (
SELECT TOP 10 CustomerName
FROM dbo.CustomerInvoice CI
JOIN dbo.Customer C ON CI.BillToCode = C.CustomerCode
WHERE InvoiceDate BETWEEN CAST(DATEADD(YEAR, -1, GETDATE()) AS SMALLDATETIME) AND CAST(GETDATE() AS SMALLDATETIME)
ORDER BY SUM(CI.Total) DESC)
GROUP BY CustomerName
ORDER BY SUM(CI.Total) DESC';
--PRINT @SQL;
EXEC sp_executesql @SQL;
基本上,您需要知道给定年份的前10名客户是什么(IN语句会告诉您这一点),但您需要使用外部查询来告知日期细分。