2013-04-26 62 views
1

這應該很簡單,但我只是無法找到答案(我將其歸咎於我已經編寫SQL近14個小時的事實)。SQL左連接,交叉連接 - 查找缺失值

我有一個名爲「標籤」字段和「ReportYear」字段的報表。我知道我有三個可能的「標籤」值,但並非每個標籤都會有每年的條目。

我可以選擇一個不同的標籤列表和獲取:

'Regular' 
'Special' 
'None' 

做一些手工數據選擇在這裏,我知道,在2011年和2010年有0項,並帶有「特殊」,但我需要一個查詢將這些信息彙總在一起,以便將其顯示出來:

'Regular' - '2012' - '5' 
'Regular' - '2011' - '2' 
'Regular' - '2010' - '1' 
'Special' - '2012' - '3' 
'Special' - '2011' - '0' 
'Special' - '2010' - '0' 
'None' - '2012' - '10' 
'None' - '2011' - '5' 
'None' - '2010' - '2' 

希望這是有道理的。

我知道我可以SELECT Count(*), Label FROM (SELECT DISTINCT Label FROM Report) t1 ...但是呢? LEFT JOIN Report t2 ON t1.Label=t2.LabelCROSS JOIN

我的大腦被炸。

幫助?

回答

1
SELECT 
    L.Label, 
    Y.ReportYear, 
    ReportCount = Count(R.Label) 
FROM 
    (SELECT DISTINCT Label FROM dbo.Report) L 
    CROSS JOIN (SELECT DISTINCT ReportYear FROM dbo.Report) Y 
    LEFT JOIN dbo.Report R 
     ON L.Label = R.Label 
     AND Y.ReportYear = R.ReportYear 
GROUP BY 
    L.Label, 
    Y.ReportYear 

現在,這並不是很理想,因爲您要做整個表掃描,兩次,以獲得標籤和年份。

除非我誤解的東西,在我看來,你應該正常化Report表,所以它有一個ReportLabelID列,然後有一個ReportLabel表具有不同的標籤。然後,您可以將ReportLabel表替換爲上面的DISTINCT查詢。

你也可以通過參數化整個查詢來接受BeginYearEndYear或類似的東西來消除ReportYear子查詢。或者,您可以從表中獲得Min(ReportYear), Max(ReportYear),並且假設您在該列上有一個索引,則可以將其轉換爲查找(可能需要兩個單獨的查詢來獲得此查詢),然後使用數字表或on-the -fly數字表格來生成它們之間的年數序列。

一旦你做了這兩個更改,查詢將顯着改善。

+0

是的!那樣做了。非常感謝! – JMax2012 2013-04-27 00:14:40

+0

不客氣。 – ErikE 2013-04-27 00:18:17