【问题标题】:I need help for a LEFT JOIN SQL query我需要 LEFT JOIN SQL 查询的帮助
【发布时间】:2013-01-03 17:43:15
【问题描述】:

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

我有 3 张桌子

  1. tJobOffer
  2. t应用程序
  3. tApplicationStatus

我想创建一个程序,返回一个 tJobOffer 列表,其中包含响应此 tJobOffer 的候选人数量。 Candidate 是我的表 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 位 Announce 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

【问题讨论】:

  • 如果您可以添加具有所需结果的示例记录以及您的问题:D,那就更好了
  • 如果你不在任何地方使用它,你为什么要加入[tApplicationStatus] AS [S]

标签: sql sql-server-2008 join


【解决方案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] ;

【讨论】:

  • 正确。谢谢你。我不知道可以加入加入。
【解决方案2】:

根据您的要求,首先您需要在必须使用内部联接之后使用左联接。

试试下面这个

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

【讨论】:

    【解决方案3】:

    试试这个:

    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]
    

    【讨论】:

      【解决方案4】:

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

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

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

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

      因此,当您需要在生成外部行之后应用过滤器并且希望过滤器是最终过滤器时,请在 WHERE 子句中指定谓词。

      【讨论】:

        猜你喜欢
        • 2013-06-19
        • 2010-09-18
        • 2011-04-03
        • 2011-05-29
        • 1970-01-01
        • 2014-04-29
        • 1970-01-01
        • 2016-07-04
        • 2016-07-26
        相关资源
        最近更新 更多