【问题标题】:Can someone explain how the following query works in Oracle10g? [closed]有人可以解释以下查询在 Oracle10g 中是如何工作的吗? [关闭]
【发布时间】:2012-01-27 23:57:51
【问题描述】:
  • 以下是两个查询。我找不到它是如何工作的。

  • 事实上,第一个查询没有返回任何值,而是第二个查询 返回几行。



   select nvl(cdm.dest_id, s.dest_id)
          from my_approval s
          left join my_alias c
          join my_destalias cdm
            on c.cust_id = 73 on cdm.alias_id = c.alias_id
           and cdm.alias_id = s.dest_id
           and s.type = 1;


 select nvl(cdm.dest_id, s.dest_id)
      from my_approval s
      left join my_alias c
        on c.cust_id = 73
      join my_destalias cdm
        on cdm.alias_id = c.alias_id
       and cdm.alias_id = s.dest_id
       and s.type = 1;

【问题讨论】:

  • 您能否详细说明您想要实现的目标,描述您的数据集、表格等。我认为虽然问题出在您的连接上,但通常您(大致)在外键上连接一个 id,所以查询 2 会返回一些东西,虽然可能不是你想要的。也许看看this 不确定oracle,但我绝对认为你的加入是错误的。
  • 您是否查看过任何一个查询的查询计划?我和@TomIngram 一起说你的连接不完整或不正确。
  • 我检查了查询计划,连接没有问题。它执行得很好。由于我在 pl/sql 块中使用了此查询,并且该表是全局临时表,因此我没有表数据。

标签: sql oracle join oracle10g left-join


【解决方案1】:

首先,这两个查询看起来像是在尝试完成相同的事情。第一个不应该执行,因为您不能有两个用于 JOIN 的 ON 子句。第二个查询看起来和第一个一样,只是有问题的 ON 子句被移到了正确的位置。

至于它是如何工作的,这个查询将从“my_approval”表中选择行。它将显示“my_destalias”表中的 dest_id。但是,如果该值为 NULL,它将显示来自“my_approval”的 dest_id。

只有在“my_destalias”表中有匹配的行时才会返回行(基于 alias_id 与“my_alias”中的 dest_id 和 alias_id 匹配),因为普通的“JOIN”关键字指定相等的连接(又名内部联接)。需要注意的是,只有当 my_destalias.alias_id 等于 BOTH my_approval.dest_id AND my_alias.alias_id 时,才会返回此查询中的行。

如果不存在匹配项 (cust_id = 73),指定给“my_alias”表的 LEFT(外部)JOIN 仍应返回数据。当然,您的内部 JOIN 取决于从该表返回的匹配项 (cdm.alias_id = c.alias_id)。我认为“c.cust_id = 73”应该是您的 WHERE 子句的一部分,并且应该在您的 LEFT JOIN 中使用下一个 JOIN 条件之一。

本质上,您的 ON 子句会使您的查询短路并限制您的结果。在不知道(确切地)你想要完成什么(或者你的表是什么样子)的情况下,试试这样的东西:

SELECT NVL(cdm.dest_id, s.dest_id)
FROM my_approval s
INNER JOIN my_alias c ON c.alias_id = s.dest_id
INNER JOIN  my_destalias cdm ON cdm.alias_id = s.dest_id
WHERE s.type = 1
AND c.cust_id = 73;

这会将所有文字值从 ON 子句中取出,并放入 WHERE 子句中。根据您的帖子,您正在尝试返回 cdm.alias_id 等于 c.alias_id 和 s.dest_id 的行。我已将这些条件放在您的 ON 子句中。基于这三个表的相互依赖程度,我选择使用两个 INNER JOIN(没有 LEFT JOIN)。

【讨论】:

  • 你是对的,但是检查 on,on 连接条件第一个连接在 my_alias 表上,第二个连接在 my_destalias 表上。并且内部连接没有产生我想要的预期结果。
【解决方案2】:

回答我的问题...

第一次查询

 select nvl(cdm.dest_id, s.dest_id)
          from my_approval s
          left join my_alias c
          join my_destalias cdm
            on c.cust_id = 73 on cdm.alias_id = c.alias_id
           and cdm.alias_id = s.dest_id
           and s.type = 1;

它的工作方式类似于左连接,连接条件c.cust_id = 73 的工作方式类似于左连接,但只有找到匹配的记录才会返回行。

第二次查询

select nvl(cdm.dest_id, s.dest_id)
      from my_approval s
      left join my_alias c
        on c.cust_id = 73
      join my_destalias cdm
        on cdm.alias_id = c.alias_id
       and cdm.alias_id = s.dest_id
       and s.type = 1;

我猜这很简单。它基于连接条件工作 (即)第一个left joinmy_aliasjoinmy_destalias。 感谢所有回答此问题的人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-12
    • 1970-01-01
    • 1970-01-01
    • 2021-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多