我有表格(列)A(a)
和B(b, a)
。
字段a
在A
中是主要的,b
是B
中的主要字段。 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。
这两个查询返回不同的行数,我不明白为什么。有人可以解释一下吗?这是我对左连接行为或其他东西的理解吗?
(不幸的是,我没有太多访问我执行它的服务器,我可能只看到返回的行数。)
答案 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
应该返回相同的结果。