我需要LEFT JOIN SQL查询的帮助

时间:2013-01-03 09:05:28

标签: sql sql-server-2008 join

我需要帮助来编写一个简单的程序。让我解释一下我要做的事情。

我有3张桌子

  1. tJobOffer
  2. TApplication的
  3. tApplicationStatus
  4. 我想创建一个程序,它返回一个tJobOffer列表,其中包含响应此tJobOffer的候选者数量。候选人是我的表tApplicationStatus的状态。此表链接到链接到tJobOffer的tApplication。申请可以是候选/接受/拒绝/忽略/ ......

    我创建了这个查询:

        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
    

4 个答案:

答案 0 :(得分: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个“应用程序”表,分组,然后将派生表与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] ;

答案 1 :(得分: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 :(得分: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]

答案 3 :(得分:0)

我不确定您是否在问为什么使用第二个LEFT JOIN的ON子句过滤的行仍显示在最终结果中。

如果这是你的问题,那么答案是:

基于ON谓词的过滤器不是最终的,即ON谓词不确定该行是否会显示在输出中,只是它是否与其他表中的行匹配。

另一方面,WHERE子句是final,在FROM子句之后处理 - 即,在处理完所有表运算符之后(在外连接的情况下),在生成所有外部行之后。

因此,如果需要在生成外部行之后应用过滤器,并且希望过滤器为final,请在WHERE子句中指定谓词。