【问题标题】:SQL Server Conditional JOIN two tablesSQL Server 条件连接两个表
【发布时间】:2015-04-29 23:06:42
【问题描述】:

我有 3 张桌子:

TableA(IDRem, IDPed, IDOP)
TableB(IDOP, IDPed)
TableC(IDPed, InvoiceDate)

我需要一个select来JOIN TableA和TableC的记录,但是有两种可能的情况:

  • 如果 TableA 上的 IDPed 不为 NULL,则通过 IDPed 直接加入 TableC
  • TableA 上的ID IDPed 为NULL,然后通过IDOp 加入TableB,然后通过IDPed 将TableB 加入TableC

到目前为止,我尝试过这个:

SELECT
    TableA.*
    ,(CASE WHEN TableC.InvoiceDate IS NULL
        THEN TableC2.InvoiceDate
        ELSE TableC.InvoiceDate
    END) AS InvoiceDate
FROM
    TableA
    LEFT JOIN TableC on TableA.IDPed = TableC.IDPed
    LEFT JOIN TableB on TableB.IDOp = TableA.IDOp
    INNER JOIN TableC as TableC2 on TableC2.IDPed = TableB.IDPed

这样做的问题是我想在选择中包含的每个字段 o tableA 我需要做一个案例......何时确定来源是 tableA 还是 TableA2。

有没有更好的方法来做到这一点?谢谢!

【问题讨论】:

    标签: sql-server


    【解决方案1】:

    对于复杂的连接,最好使用交叉应用在 TSQL 中提供服务:

    When should I use Cross Apply over Inner Join?

    select IDRem, IDPed, IDOP from TableA a
    cross apply(
        select IDOP, IDPed from TableB binner
        where a.IDop = binner.IDop
    ) b
    cross apply(
        select IDPed, InvoiceDate cinner
        where b.IDPed = cinner.IDPed
    ) c
    where ...
    

    严格来说是伪代码,但应该给你一个开始。

    【讨论】:

    • mmmm 我以前从未使用过 Cross Apply,您能否提供一个基本示例来说明在这种情况下如何使用它?谢谢!
    • 我添加了一个简单的例子(免责声明我没有检查过,所以可能并不完美)。
    • 第一部分工作:select * from TableA a cross apply(select IDOp from Tableb b where a.IDOp = b.IDOp) b 但是如果尝试做第二个交叉我没有得到任何结果
    • 我也尝试了第二张带外十字架的桌子,但没有运气
    【解决方案2】:

    您可以尝试同时使用JOINs 和使用UNION ALL

    编辑:正如 Vladimir Baranov 在评论中指出的那样,没有必要检查第一个 a.IdPed IS NULL 是否在第一个 SELECT 上,因为如果是,JOIN 将不会返回任何行。

    SELECT
        a.*,
        c.InvoiceDate
    FROM TableA a
    INNER JOIN TableC c ON c.IdPed = a.IdPed
    
    UNION ALL
    
    SELECT
        a.*,
        c.InvoiceDate
    FROM TableA a
    INNER JOIN TableB b ON b.IdOp = a.IdOP
    INNER JOIN TableC c ON c.IdPed = b.IdPed
    WHERE a.IdPed IS NULL
    

    【讨论】:

    • 在您的答案中添加解释,即在第一个 SELECT 中不需要检查 WHERE a.IdPed IS NOT NULL:当 IDPed 为 NULL 时,JOIN 将不返回任何行,所以有无需在这里明确检查。在第二个SELECT 检查是必要的。
    • 谢谢,但这似乎比我目前的尝试更复杂,加入两次 tableC。我正在寻找一个简单的答案。
    • 嗯,我认为这会更快,尤其是使用适当的索引。
    • 不是性能问题。我正在寻找一个简单的 SQL sintaxis。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 2013-12-10
    • 2017-07-05
    • 2012-09-17
    相关资源
    最近更新 更多