这是一个我快速编写的SQL查询,以便为我提供每个月PayPal购买数量的报告,该数据库是我自己构建的,基于已导入的数据。
SELECT
Items.ItemTitle,
February.Cnt As February,
March.Cnt As March,
April.Cnt As April,
May.Cnt As May,
June.Cnt As June,
July.Cnt As July,
August.Cnt As August,
September.Cnt As September
FROM
( SELECT DISTINCT ItemTitle FROM PayPalHistory ) As Items
LEFT OUTER JOIN
( SELECT ItemTitle, COUNT(*) As Cnt FROM PayPalHistory WHERE
DateTimeUtc >= '2014-02-01' AND DateTimeUtc < '2014-03-01' AND Net > 0.00
GROUP BY ItemTitle ) AS February
ON Items.ItemTitle = February.ItemTitle
LEFT OUTER JOIN
( SELECT ItemTitle, COUNT(*) As Cnt FROM PayPalHistory WHERE
DateTimeUtc >= '2014-03-01' AND DateTimeUtc < '2014-04-01' AND Net > 0.00
GROUP BY ItemTitle ) AS March
ON Items.ItemTitle = March.ItemTitle
LEFT OUTER JOIN
( SELECT ItemTitle, COUNT(*) As Cnt FROM PayPalHistory WHERE
DateTimeUtc >= '2014-04-01' AND DateTimeUtc < '2014-05-01' AND Net > 0.00
GROUP BY ItemTitle ) AS April
ON Items.ItemTitle = April.ItemTitle
LEFT OUTER JOIN
( SELECT ItemTitle, COUNT(*) As Cnt FROM PayPalHistory WHERE
DateTimeUtc >= '2014-05-01' AND DateTimeUtc < '2014-06-01' AND Net > 0.00
GROUP BY ItemTitle ) AS May
ON Items.ItemTitle = May.ItemTitle
LEFT OUTER JOIN
( SELECT ItemTitle, COUNT(*) As Cnt FROM PayPalHistory WHERE
DateTimeUtc >= '2014-06-01' AND DateTimeUtc < '2014-07-01' AND Net > 0.00
GROUP BY ItemTitle ) AS June
ON Items.ItemTitle = June.ItemTitle
LEFT OUTER JOIN
( SELECT ItemTitle, COUNT(*) As Cnt FROM PayPalHistory WHERE
DateTimeUtc >= '2014-07-01' AND DateTimeUtc < '2014-08-01' AND Net > 0.00
GROUP BY ItemTitle ) AS July
ON Items.ItemTitle = July.ItemTitle
LEFT OUTER JOIN
( SELECT ItemTitle, COUNT(*) As Cnt FROM PayPalHistory WHERE
DateTimeUtc >= '2014-08-01' AND DateTimeUtc < '2014-09-01' AND Net > 0.00
GROUP BY ItemTitle ) AS August
ON Items.ItemTitle = August.ItemTitle
LEFT OUTER JOIN
( SELECT ItemTitle, COUNT(*) As Cnt FROM PayPalHistory WHERE
DateTimeUtc >= '2014-09-01' AND DateTimeUtc < '2014-10-01' AND Net > 0.00
GROUP BY ItemTitle ) AS September
ON Items.ItemTitle = September.ItemTitle
ORDER BY
ItemTitle ASC
你在这里看到一种模式吗? :)
有没有办法可以使用循环或其他构造来消除重复LEFT OUTER JOIN ( SELECT ... )
代码?
谢谢!
答案 0 :(得分:3)
我之前没有真正写过PIVOT,但理论上它看起来像这样:
SELECT ItemTitle, [1] AS January, [2] AS February, [3] AS March, [4] AS April, [5] AS May
, [6] AS June, [7] AS July, [8] AS August, [9] AS September, [10] AS October
[11] AS November, [12] AS December
FROM
(
SELECT ItemTitle, Month(DateTimeUtc) AS [Month]
FROM PayPalHistory
WHERE DateTimeUtc >= '2014-01-01' AND DateTimeUtc < '2015-01-01' AND Net > 0.00
) p
PIVOT
(
COUNT ([Month]) FOR [Month] IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12] )
) AS pvt;
我不太确定我是否正确处理月份列名,或者Sql Server如何在此处将此整数作为列名处理,或者如何处理*
而不是聚合函数中的列名称。您可能需要将月份编号投影到字符串,作为嵌套在FROM子句中的查询的一部分,以使其工作。它肯定需要一些调整,但如果我有你的真实数据,它不会花太多工作。
或者,您可以使用嵌套的GROUP BY和SUM(CASE)方法将其转换为单个连接。单个连接仍然是必要的,以避免结果中的NULL /缺少项目,也可以通过向每个月列添加COALESCE()
函数来避免:
SELECT b.ItemTitle,
SUM(CASE WHEN [Month] = 1 THEN Cnt ELSE 0 END) As January,
SUM(CASE WHEN [Month] = 2 THEN Cnt ELSE 0 END) As February,
SUM(CASE WHEN [Month] = 3 THEN Cnt ELSE 0 END) As March,
SUM(CASE WHEN [Month] = 4 THEN Cnt ELSE 0 END) As April,
SUM(CASE WHEN [Month] = 5 THEN Cnt ELSE 0 END) As May,
SUM(CASE WHEN [Month] = 6 THEN Cnt ELSE 0 END) As June,
SUM(CASE WHEN [Month] = 7 THEN Cnt ELSE 0 END) As July,
SUM(CASE WHEN [Month] = 8 THEN Cnt ELSE 0 END) As August,
SUM(CASE WHEN [Month] = 9 THEN Cnt ELSE 0 END) As September,
SUM(CASE WHEN [Month] = 10 THEN Cnt ELSE 0 END) As October,
SUM(CASE WHEN [Month] = 11 THEN Cnt ELSE 0 END) As November,
SUM(CASE WHEN [Month] = 12 THEN Cnt ELSE 0 END) As December
FROM (SELECT DISTINCT ItemTitle FROM PayPalHistory) b
LEFT JOIN (
SELECT ItemTitle, COUNT(*) As Cnt, MONTH(DatetimeUtc) As [Month]
FROM PayPalHistory
WHERE DateTimeUtc >= '2014-01-01' AND DateTimeUtc < '2015-01-01' AND Net > 0.00
GROUP BY ItemTitle, MONTH(DateTimeUtc)
) m on m.ItemTitle = b.ItemTitle
GROUP BY b.ItemTitle
这里仍然有一些重复的代码,但我认为你会同意它比原来的巨大的改进...我还有很多信心这实际上会起作用;)
答案 1 :(得分:2)
此PIVOT查询可能是您想要的,请试一试:
SELECT
ItemTitle,
[January], [February], [March], [April],
[May], [June], [July], [August],
[September],[October], [November],[December]
FROM
(
SELECT ItemTitle, DATENAME(MONTH, DateTimeUtc) Month
FROM paypalhistory
WHERE Net > 0.0 AND DateTimeUtc >= '2014-01-01' AND DateTimeUtc < '2015-01-01'
) AS p
PIVOT ( COUNT (Month) FOR Month IN
( [January], [February], [March], [April], [May], [June],
[July], [August], [September],[October], [November], [December] )
) AS pvt
ORDER BY ItemTitle;
答案 2 :(得分:0)
你的意思是PIVOT?
你可以在DATEPART(月,DateTimeUtc)上潜伏......
答案 3 :(得分:0)
SELECT
ItemTitle
, SUM( CASE WHEN DateTimeUtc >= '2014-01-01' AND DateTimeUtc < '2014-02-01' AND Net > 0.00 THEN 1 ELSE 0 END ) As January
, SUM( CASE WHEN DateTimeUtc >= '2014-02-01' AND DateTimeUtc < '2014-03-01' AND Net > 0.00 THEN 1 ELSE 0 END ) As February
, SUM( CASE WHEN DateTimeUtc >= '2014-03-01' AND DateTimeUtc < '2014-04-01' AND Net > 0.00 THEN 1 ELSE 0 END ) As March
, SUM( CASE WHEN DateTimeUtc >= '2014-04-01' AND DateTimeUtc < '2014-05-01' AND Net > 0.00 THEN 1 ELSE 0 END ) As April
, SUM( CASE WHEN DateTimeUtc >= '2014-05-01' AND DateTimeUtc < '2014-06-01' AND Net > 0.00 THEN 1 ELSE 0 END ) As May
, SUM( CASE WHEN DateTimeUtc >= '2014-06-01' AND DateTimeUtc < '2014-07-01' AND Net > 0.00 THEN 1 ELSE 0 END ) As June
, SUM( CASE WHEN DateTimeUtc >= '2014-07-01' AND DateTimeUtc < '2014-08-01' AND Net > 0.00 THEN 1 ELSE 0 END ) As July
, SUM( CASE WHEN DateTimeUtc >= '2014-08-01' AND DateTimeUtc < '2014-09-01' AND Net > 0.00 THEN 1 ELSE 0 END ) As August
, SUM( CASE WHEN DateTimeUtc >= '2014-09-01' AND DateTimeUtc < '2014-10-01' AND Net > 0.00 THEN 1 ELSE 0 END ) As September
, SUM( CASE WHEN DateTimeUtc >= '2014-10-01' AND DateTimeUtc < '2014-11-01' AND Net > 0.00 THEN 1 ELSE 0 END ) As October
, SUM( CASE WHEN DateTimeUtc >= '2014-11-01' AND DateTimeUtc < '2014-12-01' AND Net > 0.00 THEN 1 ELSE 0 END ) As November
, SUM( CASE WHEN DateTimeUtc >= '2014-12-01' AND DateTimeUtc < '2015-01-01' AND Net > 0.00 THEN 1 ELSE 0 END ) As December
FROM PayPalHistory
GROUP BY ItemTitle
答案 4 :(得分:0)
按月计算的计数组按年份过滤到临时@var表,然后转到最终选择。 你能试试吗?如果需要,我可以在这里创建一个迷你数据库来帮助你。