从 tables 中选择匹配行与来自 table 匹配条件的值连接

Selecting matching rows from tables in join with values from either table matching a condition

场景

三个表:

关系

目标

是 select orders 中满足 either 列条件的任何项目客户delivery_addresses。在更实际的意义上:我想搜索存储在 either customers 中的具有特定名称(或邮政编码或其他)的客户订单delivery_addresses.

我的尝试

我不太了解联接及其背后的逻辑,但经过扎实的研究后,我想出了这个:

SELECT orders.* FROM orders INNER JOIN customers ON orders.customerId = customers.id INNER JOIN delivery_addresses ON orders.customerId = delivery_addresses.customerId WHERE ((customers.first_name LIKE "%max%") OR (delivery_addresses.first_name LIKE "%max%"))

但是,这不起作用。如果 delivery_addresses 中有相应的条目,我只会得到结果,但如果 customers.[= 中只有一个条目,我就不会得到结果13=]

因此,如果我像这样缩短查询:

SELECT orders.* FROM orders INNER JOIN customers ON orders.customerId = customers.id WHERE (customers.first_name LIKE "%max%")

我确实得到了正确的结果。

结论

我确信我遗漏了关于我对联接如何工作的理解的关键点。但是我不知道它是什么。

这里INNER JOIN就像一个过滤器

SELECT orders.* 
FROM orders 
INNER JOIN customers ON orders.customerId = customers.id 
INNER JOIN delivery_addresses ON orders.customerId = delivery_addresses.customerId 
WHERE ((customers.first_name LIKE "%max%") 
  OR (delivery_addresses.first_name LIKE "%max%"))

可以使用LEFT JOIN重写:

SELECT orders.* 
FROM orders 
INNER JOIN customers ON orders.customerId = customers.id 
LEFT JOIN delivery_addresses ON orders.customerId = delivery_addresses.customerId 
WHERE customers.first_name LIKE '%max%'
   OR delivery_addresses.first_name LIKE'%max%
    

或者使用 UNION:

SELECT orders.* 
FROM orders 
INNER JOIN customers ON orders.customerId = customers.id 
WHERE customers.first_name LIKE '%max%'
UNION
SELECT orders.* 
FROM orders 
INNER JOIN customers ON orders.customerId = customers.id 
INNER JOIN delivery_addresses ON orders.customerId = delivery_addresses.customerId 
WHERE delivery_addresses.first_name LIKE'%max%

您可以使用 LEFT 连接和 ON 子句中的所有条件来完成:

SELECT o.* 
FROM orders o 
LEFT JOIN customers c ON o.customerId = c.id AND c.first_name LIKE "%max%"
LEFT JOIN delivery_addresses d ON o.customerId = d.customerId AND d.first_name LIKE "%max%"
WHERE c.id IS NOT NULL OR d.customerId IS NOT NULL

如果您得到重复的行,您可能必须在 SELECT 之后添加 DISTINCT

SELECT DISTINCT o.*
....................