繁体   English   中英

左外连接产生意外结果

[英]LEFT OUTER JOIN GIVING UNEXPECTED RESULT

我正在做一个简单的查询:

SELECT * FROM Bench LEFT JOIN  ASSIGNED_DOM 
        ON (Bench.B_id=ASSIGNED_DOM.B_id)  WHERE Bench.B_type=0 ;

不出所料,返回了Bench表的所有行,但是如果我尝试获取B_id字段,我发现该字段被置为NULL。 然后,我尝试了另一个完全等效的查询:

SELECT * FROM Bench LEFT JOIN  ASSIGNED_DOM USING (B_id)  WHERE Bench.B_type=0 ;

但是在那种情况下,B_id字段会正确返回。 第一个查询出了什么问题? 两者有什么区别?

如果列名相同,则第二个表中的值将覆盖第一个表中的值。 尝试在查询中使用别名

SELECT Bench.B_id AS bid1, ASSIGNED_DOM.B_id AS bid2 
FROM Bench 
LEFT JOIN  ASSIGNED_DOM ON (Bench.B_id=ASSIGNED_DOM.B_id) 
WHERE Bench.B_type=0;

这两个查询相等。 根据文档

自然连接和使用USING的连接(包括外部连接变体)均根据SQL:2003标准进行处理。

NATURAL连接的冗余列不会出现

具体来说,可以归结为以下差异:

可以将USING子句重写为比较相应列的ON子句。 但是,尽管USING和ON相似,但它们并不完全相同。

关于确定哪些行满足连接条件,两个连接在语义上是相同的。

关于确定要为SELECT *扩展显示的列,两个联接在语义上并不相同。 USING联接选择相应列的合并值, 而ON联接从所有表中选择所有列

因此,您的第一个查询具有两列相同名称的bench.B_id, ASSIGNED_DOM.B_id ,而第二个查询只有一coalesce(bench.B_id, ASSIGNED_DOM.B_id) as B_id

这将取决于您的应用程序/框架如何正确处理第一种情况。 例如,MySQL客户端或phpmyadmin将仅显示所有列。 一些框架可能会以某种方式更改名称以使其唯一。

特别是php (我假设您正在使用它)不会:如果您使用$row['B_id'] ,它将返回最后一次出现(尽管未指定行为),因此在您的情况下,您将获得ASSIGNED_DOM.B_id 但是,您仍然可以使用其索引访问两个列(例如$row[0]$row[1] ),但只能访问具有相同列名的列中的一个。

为避免此类问题,您可以/应该使用别名,例如select bench.B_id as bench_B_id, ASSIGNED_DOM.B_id as ASSIGNED_DOM_B_id, ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM