2014-10-02 113 views
0

這是一個SQL查詢,我很快寫了一個關於每個月PayPal購買數量的報告,數據庫是基於已導入數據的我自己的構建。根據月份重複JOIN

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 ...)代碼?

謝謝!

+1

我認爲你需要一個'PIVOT'。首先使用ItemTitle,Month,Count進行表格查詢。之後,嘗試「樞軸」或使用類似的技術。像[this](http://sqlhints.com/2014/03/10/pivot-and-unpivot-in-sql-server/)。 – 2014-10-02 20:58:40

回答

0

你的意思是像一個PIVOT

你可以PIVOT上DATEPART(月,DateTimeUtc)...

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 
0

通過網絡和年月過濾到一個臨時表@var然後轉動到您的最終選擇次數羣。 你可以試試嗎?如果你需要,我可以在這裏創建一個迷你分貝來幫助你。

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; 
3

我還沒有真正寫的前一個支點,但在理論上它看起來像這樣:

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)方法將其歸結爲單個連接。單加盟仍然是必要的,以避免空值/在結果中丟失物品,也可能是通過增加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 

目前仍然在這裏一些重複的代碼,但我認爲你會同意這是一個巨大的改善比原來...我有更多的信心,這將實際上工作;)

+0

整潔的方式處理月份的替代版本! – 2014-10-02 21:27:04

+0

對於數據透視,聚合需要針對特定​​的列,例如count(mth),而IN子句的值需要使用[1],[2]等括號,因爲標識符無法啓動與一個數字。 – jpw 2014-10-02 21:39:48

+1

你應該更多地寫PIVOTs他們很有趣。 – Taryn 2014-10-02 21:44:17