2013-01-03 30 views
0

我需要幫助來編寫一個簡單的過程。讓我解釋我想要做的事情。我需要LEFT JOIN SQL查詢的幫助

我有3個表

  1. tJobOffer
  2. TApplication的
  3. tApplicationStatus

我想創建返回我tJobOffer列表與迴應的候選人數的程序到這個tJobOffer。候選人是我的表tApplicationStatus的狀態。該錶鏈接到與tJobOffer鏈接的tApplication。應用程序可以是候選人/接受/ REFUSED/IGNORED/...

我創造了這個查詢:

SELECT 
     [T].[JobOfferId], 
     [T].[JobOfferTitle], 
     COUNT([A].[ApplicationId]) AS [CandidateCount] 

    FROM  [tJobOffer] AS [T] 
    LEFT JOIN [tApplication] AS [A] 
     ON  [A].[JobOfferId] = [T].[JobOfferId] 
    LEFT JOIN [tApplicationStatus] AS [S] 
     ON  [S].[ApplicationStatusId] = [A].[ApplicationStatusId] 
     AND  [S].[ApplicationStatusTechnicalName] = 'CANDIDATE' 

    GROUP BY 
      [T].[JobOfferId], 
      [T].[JobOfferTitle] 
      --[A].[ApplicationStatusId] 

    ORDER BY [T].[JobOfferTitle] 

結果是

> 52ED7C67-21E1-49BB-A1F8-0601E6EED1EA Annonce 1 0 
> F26B228D-0C81-4DA8-A287-F8F997CC1F9C Annonce 1b 0 
> 9DA60B23-F113-4C7F-9707-2B90C1556D5D Announce 25 2 
> 258E11A7-79C1-47B6-8C61-413AA54E2360 Announce 3 0 
> DA582383-5DF4-4E1D-837C-382371BDEF57 Announce 6 2 

這是不正確的,因爲我只有1候選人宣佈6.如果一套我的線

--AND  [S].[ApplicationStatusTechnicalName] = 'CANDIDATE' 

在評論結果是一樣的。我的查詢似乎忽略了這一行。哪裏不對?

編輯 -

我正確的結果應該是

> 52ED7C67-21E1-49BB-A1F8-0601E6EED1EA Annonce 1 0 
> F26B228D-0C81-4DA8-A287-F8F997CC1F9C Annonce 1b 0 
> 9DA60B23-F113-4C7F-9707-2B90C1556D5D Announce 25 2 
> 258E11A7-79C1-47B6-8C61-413AA54E2360 Announce 3 0 
> DA582383-5DF4-4E1D-837C-382371BDEF57 Announce 6 1 
+2

好得多,如果你可以用你的問題'與期望的結果阿玲加樣品記錄:D' –

+0

你爲什麼加入'[tApplicationStatus] AS [S]'如果你是不在任何地方使用它? –

回答

1

我想你想的:

SELECT 
    [T].[JobOfferId], 
    [T].[JobOfferTitle], 
    COUNT([A].[ApplicationId]) AS [CandidateCount] 

FROM  [tJobOffer] AS [T] 
LEFT JOIN [tApplication] AS [A] 
    INNER JOIN [tApplicationStatus] AS [S] 
     ON  [S].[ApplicationStatusId] = [A].[ApplicationStatusId] 
     AND  [S].[ApplicationStatusTechnicalName] = 'CANDIDATE' 
    ON  [A].[JobOfferId] = [T].[JobOfferId] 

GROUP BY 
     [T].[JobOfferId], 
     [T].[JobOfferTitle] 

ORDER BY [T].[JobOfferTitle] ; 

你也可以加入首先是2個「應用程序」表S,由組,然後加入派生表JobOffer

SELECT 
    [T].[JobOfferId], 
    [T].[JobOfferTitle], 
    COALESCE([G].[Cnt], 0) AS [CandidateCount] 

FROM  [tJobOffer] AS [T] 
LEFT JOIN 
      (SELECT 
        [A].[JobOfferId], 
        COUNT(*) AS [Cnt] 

       FROM  [tApplication] AS [A] 
       INNER JOIN [tApplicationStatus] AS [S] 
        ON  [S].[ApplicationStatusId] = [A].[ApplicationStatusId] 
        AND  [S].[ApplicationStatusTechnicalName] = 'CANDIDATE' 

       GROUP BY 
          [A].[JobOfferId] 
      ) AS [G] 
    ON  [G].[JobOfferId] = [T].[JobOfferId] 

ORDER BY [T].[JobOfferTitle] ; 
+0

正確。謝謝。我不知道有可能加入加入。 –

0

試試這個:

SELECT 
     [T].[JobOfferId], 
     [T].[JobOfferTitle], 
     COUNT([A].[ApplicationId]) AS [CandidateCount] 

    FROM  [tJobOffer] AS [T] 
    LEFT JOIN [tApplication] AS [A] 
     ON  [A].[JobOfferId] = [T].[JobOfferId] 
    LEFT JOIN 
     (SELECT ApplicationStatusId FROM [tApplicationStatus] 
      WHERE [ApplicationStatusTechnicalName] = 'CANDIDATE') [S] 
     ON  [S].[ApplicationStatusId] = [A].[ApplicationStatusId] 
    GROUP BY 
      [T].[JobOfferId], 
      [T].[JobOfferTitle] 
    ORDER BY [T].[JobOfferTitle] 
0

我不知道你會問,爲什麼你用左二的ON子句過濾行JOIN仍然在最終結果中顯示出來。

如果這是你的問題,那麼答案是:

基礎上,謂詞過濾器是不是終點,即謂詞並不確定該行是否會出現在輸出時,只有它是否將與另一個表中的行匹配。

另一方面,WHERE子句是final的,在FROM子句之後進行處理 - 即在所有的表操作符被處理之後,以及(在外連接的情況下),在所有的外行被生成之後。

因此,當您需要在生成外部行之後應用過濾器,並且希望過濾器爲最終過濾器時,請在WHERE子句中指定謂詞。

1

根據您的要求,首先您需要在使用內部連接後使用左側連接。

嘗試下面的一個

SELECT 
    [T].[JobOfferId], 
    [T].[JobOfferTitle], 
    COUNT([A].[ApplicationId]) AS [CandidateCount] 

FROM  [tJobOffer] AS [T] 
LEFT JOIN [tApplication] AS [A] 
    INNER JOIN [tApplicationStatus] AS [S] 
     ON  [S].[ApplicationStatusId] = [A].[ApplicationStatusId] 
     AND  [S].[ApplicationStatusTechnicalName] = 'CANDIDATE' 
    ON  [A].[JobOfferId] = [T].[JobOfferId] 

GROUP BY 
     [T].[JobOfferId], 
     [T].[JobOfferTitle] 

ORDER BY [T].[JobOfferTitle] ;