我有两个表TAB_A和TAB_B。TAB_A是主表,TAB_B是子表/事务表。TAB_A具有COL_A(主键),而TAB_B具有COL_B(主键),也具有COL_A。 由于某些业务原因,未在列COL_A的TAB_A和TAB_B之间定义外键。 TAB_B中有四个记录,其中COL_A中的一些值分别为1、2、3和4,而TAB_A的COL_A中没有相应的匹配值。(它们是孤立记录,是错误创建的) 当我发出以下SELECT查询时,我得到了四个记录 SELECT B.COL_B, B.COL_A FROM TAB_A A, TAB_B B WHERE A.COL_A = B.COL_A AND B.COL_A IN (1, 2, 3, 4) 但是,如果我开始在SELECT查询中引用A.COL_A,则不会返回任何记录。 SELECT B.COL_B, B.COL_A, A.COL_A FROM TAB_A A, TAB_B B WHERE A.COL_A = B.COL_A AND B.COL_A IN (1, 2, 3, 4) 有人可以解释这种奇怪的行为吗? AIX中的DB2版本9.5
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
这种看似矛盾的行为实际上是由SQL的处理逻辑和JOIN操作的本质所导致的。在你的第一个查询中:
SELECT B.COL_B, B.COL_A
FROM TAB_A A, TAB_B B
WHERE A.COL_A = B.COL_A AND B.COL_A IN (1, 2, 3, 4)
这个查询使用了旧式的连接语法(隐式交叉连接后跟WHERE子句),它等同于一个内连接(INNER JOIN)。在这个查询中,尽管TAB_A中没有与TAB_B中COL_A值为1、2、3、4匹配的记录,但由于你直接从TAB_B表中选择了这些列,所以那些不匹配TAB_A的记录依然会被返回。这是因为对于IN列表中的每个值,SQL引擎尝试找到A.COL_A和B.COL_A相等的行,找不到匹配时,不会过滤掉B表中的行,因为它们满足WHERE子句的第二个条件。
然而,在第二个查询中:
SELECT B.COL_B, B.COL_A, A.COL_A
FROM TAB_A A, TAB_B B
WHERE A.COL_A = B.COL_A AND B.COL_A IN (1, 2, 3, 4)
你不仅选择了B表的列,还试图选择A表的列。由于A表中没有与这些错误创建的记录相对应的COL_A值,当SQL执行内连接时,它寻找的是两个表中COL_A相等的行对。因为不存在这样的匹配行对(即A表中没有COL_A为1、2、3或4的记录),结果集就是空的。即使B表中有这些记录,但因为它们不能与A表中的任何记录配对,所以最终结果集中不会包含这些记录。
简而言之,当你只从TAB_B表中选择列时,那些孤立的记录仍然可以被单独返回,因为它们自身满足WHERE条件。但是一旦你尝试同时从TAB_A和TAB_B中选择列(特别是当涉及到TAB_A的列时),如果没有匹配的行存在于TAB_A中,那么整个组合(即包括A表和B表列的行)就不会出现在结果集中,从而导致没有返回记录。