【问题标题】:Odd Outer Joining Structure for a View视图的奇数外部连接结构
【发布时间】:2019-12-04 03:37:55
【问题描述】:

作为软件升级的一部分,我正在从旧数据库导入视图,我在工作时看到了这个FROM 子句。

FROM 
    t_store_master AS STM 
RIGHT OUTER JOIN 
    dbo.t_shipping AS SHP 
INNER JOIN 
    t_hu_master AS HUM 
INNER JOIN 
    t_stored_item AS STO ON HUM.hu_id = STO.hu_id
      ON SHP.shipment_id = HUM.reserved_for 
      AND SHP.location_id = HUM.location_id 
INNER JOIN 
    dbo.t_carrier AS CAR ON SHP.carrier_code = CAR.carrier_code 
LEFT OUTER JOIN 
    dbo.t_order_detail AS ORD 
INNER JOIN 
    dbo.t_order AS ORM ON ORD.order_number = ORM.order_number
INNER JOIN 
    dbo.t_pick_detail PDL ON ORD.order_number = PDL.order_number
       ON STO.type = PDL.pick_id
       ON STM.store_id = HUM.control_number_2

据我了解,OUTER JOIN 需要 ON 子句才能被编译器正确解释。但是,肯定有一些我不知道的极端情况,因为上面的代码返回了良好的数据而不会引发任何错误。

在对 OUTER JOINs 的 MSDN 标准进行了一些观察和阅读之后,我仍然不知道 LEFT OUTER JOIN 和 RIGHT OUTER JOIN 在此查询中所做的事情。

我知道INNER JOINs 下的多个ON 子句是必要的。在ON 子句和OUTER JOINs 之间似乎存在某种隐藏或隐含的映射。过去,我无法说出以这种方式编写查询的目的是什么。

有人能解释一下它是如何工作的以及为什么会这样写吗?

【问题讨论】:

    标签: sql sql-server join view


    【解决方案1】:

    这是允许的。括号更有意义:

    FROM t_store_master STM RIGHT OUTER JOIN
         (dbo.t_shipping SHP INNER JOIN
          (t_hu_master HUM INNER JOIN
           t_stored_item STO 
           ON HUM.hu_id = STO.hu_id
          )
          ON SHP.shipment_id = HUM.reserved_for AND
             SHP.location_id = HUM.location_id 
         ) INNER JOIN
         (dbo.t_carrier CAR 
          ON SHP.carrier_code = CAR.carrier_code LEFT OUTER JOIN
          ((dbo.t_order_detail ORD INNER JOIN
            dbo.t_order ORM 
            ON ORD.order_number = ORM.order_number
           ) INNER JOIN
           dbo.t_pick_detail PDL
           ON ORD.order_number = PDL.order_number
          )
          ON STO.type = PDL.pick_id
         )
         ON STM.store_id = HUM.control_number_2
    

    也就是说,我建议从不编写这样的查询并尽快重写查询(如果它在生产代码中)。至少,加上括号!

    在FROM 子句中几乎不需要括号来表达JOINs(有一种情况我碰巧使用了它们)。永远不需要非交错的ON 子句——或者至少,我从来没有机会使用它们或认为它们是编写查询的最佳方式。但是,两者都是允许的。

    【讨论】:

    • 这个查询 SELECT * FROM TEST LEFT JOIN TEST as TEST2 LEFT JOIN TEST as TEST3 ON TEST2.i=TEST3.i ON TEST3.i = TEST.i WHERE TEST.i<=3 有效,所以上面的意义...
    • 谢谢戈登。遇到这个问题的同事问我是怎么想的。我告诉他我以前从未见过这样的事情,但我可以问@Gordon Linoff。没想到你会再坚持几个小时。我将测试括号,然后接受答案。你能大胆猜测一下为什么有人会这样写查询吗?
    • @爱德华。 . .我的第一个猜测是故意混淆。很少有 SQL 用户意识到 ON 子句不需要交错。也许代码是从旧式的joins 转换的,其中where 子句按照它们出现的顺序变成了on 子句。如果您注意到,您必须重新排列 on 子句以交错 ONs。
    • 为了完整起见,我想说整个FROM 子句都被废弃了。我们继续使用更简单的INNER JOIN 格式重新编写了这个连接。我要补充一点,几个有经验的开发人员尝试拼凑这个查询正在做什么并且失败了。甚至 Gordon 的最终答案都包含错误。他仍然给出了正确的答案,即永远不要在 PROD 环境中使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    • 2012-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 1970-01-01
    相关资源
    最近更新 更多