【问题标题】:Multiple left joins in a single statement单个语句中的多个左连接
【发布时间】:2019-07-08 14:35:29
【问题描述】:

我有多个查询,我试图将它们组合成一个查询,但没有成功。我在同一张表上两次使用不同字段的左连接,这听起来不对。

SELECT a.* 
     , b.CODE_DESCRIPTION AS highest_grade 
  FROM BBOP.EP_MAIN_FACT a 
       LEFT JOIN BBOP.EP_CODE_WORK b 
              ON a.HIGHESTGRADE_CA = b.code
             AND code_type LIKE 'High%'
       LEFT JOIN BBOP.EP_CODE_WORK ab 
              ON a.Goal_Steps = ab.code
             AND code_type LIKE 'Goal%'
 WHERE plan_date BETWEEN '01-mar-2019' AND '31-may-2019';

-- ORA-00918: 列定义不明确 00918. 00000 - “列定义不明确”

这是 2 个查询,它们分别产生没有问题的结果。

-- 最高等级

SELECT a.* 
     , b.CODE_DESCRIPTION AS highest_grade_desc 
  FROM BBOP.EP_MAIN_FACT a 
       LEFT JOIN BBOP.EP_CODE_WORK b 
              ON a.HIGHESTGRADE_CA = b.code
 WHERE plan_date BETWEEN '01-mar-2019' AND '31-may-2019'
   AND code_type LIKE 'High%';

-- 目标

SELECT a.* 
     , b.CODE_DESCRIPTION AS Goal 
  FROM BBOP.EP_MAIN_FACT a 
       LEFT JOIN BBOP.EP_CODE_WORK b 
              ON a.Goal_Steps = b.code
 WHERE plan_date BETWEEN '01-mar-2019' AND '31-may-2019'
   AND code_type LIKE 'Goal%';

【问题讨论】:

  • 我用 oracle 重新标记了您的问题,因为错误消息清楚地表明您使用的是 Oracle,而不是 Microsoft SQL Server。
  • 向我们展示数据库架构、示例数据、当前和预期输出。请阅读How-to-Ask 这里是START 了解如何提高问题质量并获得更好答案的好地方。 How to create a Minimal, Complete, and Verifiable example
  • @a_horse_with_no_name 是的,它的 Orcale 很抱歉,目前都打开了,所以我把它们弄混了。
  • 在第一个查询的第 4,6 和 7 行使用 code_typeplan_date 之前的表的别名
  • 问题的解决方案 (ORA-00918) 是正确地为每一列加上它来自的表名。

标签: sql oracle


【解决方案1】:

我想你想要:

select mf.*, coalesce(cwh.CODE_DESCRIPTION, cwg.CODE_DESCRIPTION) as highest_grade 
from BBOP.EP_MAIN_FACT mf left join
     BBOP.EP_CODE_WORK cwh
     on mf.HIGHESTGRADE_CA = cwh.code and
        cwh.code_type like 'High%' left join
     BBOP.EP_CODE_WORK cwg
     on mf.Goal_Steps = cwg.code and
        cwg.code_type like 'Goal%'
where mf.plan_date >= date '2019-03-01' and
      mf.plan_date < date '2019-06-01';

注意事项:

  • 在引用多个表的查询中,限定所有列引用。这是你问题的根源。 on 子句中有“裸”列引用。
  • 使用有意义的表别名,而不是任意字母。
  • coalesce() 根据连接的优先级顺序选择值。
  • Oracle 支持date 关键字来引入日期文字。这比依赖可能在给定服务器上更改的默认格式更安全。
  • between 对日期很危险,尤其是在 Oracle 中,date 类型始终具有时间组件。不等式抓住了逻辑。

【讨论】:

    【解决方案2】:

    正如有人在 cmets 中所说,plan_date 和 code_type 列需要在其用法中指定表别名。

    我猜这些列中至少有一个列在 BBOP.EP_CODE_WORK 表中,因此在引用这些列时需要指定表别名。

    问候 阿卡什

    【讨论】:

      猜你喜欢
      • 2016-03-22
      • 2018-12-16
      • 2016-06-21
      • 1970-01-01
      • 2018-11-25
      • 1970-01-01
      • 2021-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多