SQL左连接和手动空加法

时间:2013-09-23 02:17:18

标签: sql

我有表格(列)A(a)B(b, a)。 字段aA中是主要的,bB中的主要字段。 A表示一组类,B表示一组元素,每个元素都是一个类的一部分。 任务是检索所有类(A.a)是第一列和第二列中这些类的元素。如果某个类不包含元素,则应在第二列中使用null检索它。

正确的查询是:

select A.a, B.b from A left join B on A.a = B.a

这正是我所需要的。但是,在阅读了左连接的文档后,我尝试使用查询手动重复此结果:

select B.a, B.b as "b" from B
union
select A.a, null as "b" from A
where A.a not in (select B.a from B)

第一行选择我需要的所有对,第3行选择那些未在表B中呈现的类,第二列中为null。 这两个查询返回不同的行数,我不明白为什么。有人可以解释一下吗?这是我对左连接行为或其他东西的理解吗? (不幸的是,我没有太多访问我执行它的服务器,我可能只看到返回的行数。)

3 个答案:

答案 0 :(得分:1)

(注意:这是第一次发布为评论。)

如果B.a可以有NULL并且某些行在该列中确实有NULL,则第二个查询的第二部分将不返回任何内容。这是因为x NOT IN (list)基本上转化为

 x <> value1 AND x <> value2 AND ...

当至少有一个值为NULL时,该特定<>谓词的计算结果为UNKNOWN,如果所有其他谓词的计算结果为TRUE,则整个条件也变为UNKNOWN(TRUE AND UNKNOWN产生UNKNOWN,根据{{​​3}})。

根据B行中{NULL} B.a行与A行未引用的B行之间的比率,整个第二个查询可以返回{{3} }或three-valued logic比第一个查询,但两个查询也可能返回more

另一种可能性是A中存在对不存在的B行的引用(这意味着没有外键来保证引用完整性)。如果存在此类行,则第一个查询将返回fewer rows而不是第二个查询,因为它将排除无效引用,而第二个查询将包含它们。

答案 1 :(得分:0)

Union会将所有空值视为单个空值,这可能不是您所期望的。有两种方法:

1. Use UNION ALL
2. Use non distinct "type Fields"...


    SELECT
          Type="Type1",
          Amount
       FROM 
         Table

       UNION

       SELECT
          Type="Type2",
          Amount
       FROM 
          Table

答案 2 :(得分:0)

假设你有这样的数据:

Table A
1
2
3
4

Table B
1, A
1, B
2, A
3, F
3, F

UNION将消除发生的任何重复结果。在这种情况下,“3,F”仅列出一次。否则结果将是相同的。 UNION ALL应该返回相同的结果。

请参阅此SQL Fiddle example