如何在SQL中使用联接

时间:2020-05-11 23:20:12

标签: mysql sql database join left-join

这是我要了解的问题:

假设一个网站包含两个表,Customers表和Orders表。

编写SQL查询以查找从未订购任何商品的所有客户。

表:客户。

+----+-------+
| Id | Name  |
+----+-------+
| 1  | Joe   |
| 2  | Henry |
| 3  | Sam   |
| 4  | Max   |
+----+-------+

表:订单。

+----+------------+
| Id | CustomerId |
+----+------------+
| 1  | 3          |
| 2  | 1          |
+----+------------+

以上述表格为例,返回以下内容:

+-----------+
| Customers |
+-----------+
| Henry     |
| Max       |
+-----------+

解决方案:

SELECT Name AS Customers 
FROM Customers AS c LEFT JOIN Orders AS o ON c.Id = o.CustomerId
WHERE o.Id IS NULL;

有人知道我们为什么使用c.Id = o.CustomerId来匹配列,为什么我们选择o.Id为Null而不选择其他列?

4 个答案:

答案 0 :(得分:1)

正如Kevin所提到的,CustomerId是Orders表的外键。 left outer join将两个表与具有在联接条件中指定的匹配数据的行组合在一起;如果没有匹配数据,则为null。这意味着left outer join使用c.Id = o.CustomerId将创建以下表格选择:

+------+--------+------+--------------+
| c.Id | c.Name | o.Id | o.CustomerId |
+------+--------+------+--------------+
|   1  | Joe    |  2   |     1        |
|   2  | Henry  | NULL |    NULL      |
|   3  | Sam    |  1   |     3        |
|   4  | Max    | NULL |    NULL      |
+----+----------+------+--------------+

如果我们使用上表中的where子句WHERE o.Id IS NULL进行选择,我们将收到ID为2和4的行,因为o.Id对于这些行为空。

答案 1 :(得分:0)

原因是因为CustomerId表中的Orders列是Id表中Customers列的外键。因此,要正确连接这两个表,请在这两列上。

我认为这些列的命名不正确,如果在两个表中都使用CustomerId,那将更有意义。

答案 2 :(得分:0)

已经解释了现有查询的工​​作原理。

我发现not exists是表达此查询的一种更简单明了的方式:

select c.*
from customers c
where not exists (select 1 from orders o where o.customer_id = c.id)

使用orders(custmer_id)上的索引,这实际上可能比反左联接解决方案的效果更好。

答案 3 :(得分:-1)

Does anyone know why we are using c.Id = o.CustomerId to match the columns?

因为我们通过这些列生成2个表。我们可能会使用其他产品,并且产品可能会有所不同。

Why we are choosing o.Id to be Null and not the other columns? 

这是一个过滤器,您可以使用所需的任何条件,结果集也可以不同。

P.S。在大多数情况下,LEFT会在主键上加入过滤器(但之后会变成INNER JOIN)

相关问题