Mysql 从联接中的表中选择与条件匹配的表中的值匹配的行

Mysql 从联接中的表中选择与条件匹配的表中的值匹配的行,mysql,join,inner-join,Mysql,Join,Inner Join,场景 三张表: 命令 顾客 送货地址 关系 订单.customerId指向客户.id 订单.customerId指向交货地址.customerId 目标 是从订单中选择满足客户或交货地址中列条件的任何项目。从更实际的意义上说:我想搜索具有存储在中的某个名称(或邮政编码或任何内容)的客户订单,或者客户或者送货地址 我的尝试 我对连接及其背后的逻辑不太了解,但经过深入研究后,我得出了以下结论: 选择订单。*从订单内部加入订单上的客户。customerId=customers.id内部加入订单

场景

三张表:

  • 命令
  • 顾客
  • 送货地址
关系

  • 订单.customerId指向客户.id
  • 订单.customerId指向交货地址.customerId
目标

是从订单中选择满足客户交货地址中列条件的任何项目。从更实际的意义上说:我想搜索具有存储在中的某个名称(或邮政编码或任何内容)的客户订单,或者客户或者送货地址

我的尝试

我对连接及其背后的逻辑不太了解,但经过深入研究后,我得出了以下结论:

选择订单。*从订单内部加入订单上的客户。customerId=customers.id内部加入订单上的交货地址。customerId=delivery\u addresses.customerId其中((customers.first\u name,如“%max%”)或(delivery\u addresses.first\u name,如“%max%”)

然而,这是行不通的。只有在配送地址中有相应的条目时,我才会得到结果,但在客户中只有一个条目时,我不会得到结果

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

选择订单。*从订单内部加入订单上的客户。customerId=customers.id其中(customers.first\u name,如“%max%”

我确实得到了正确的结果

结论


我确信,在我对如何工作的理解方面,我错过了一个关键点。但是我不知道它是什么。

这里
内部连接就像一个过滤器

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%"))
可以使用
左连接重写它:

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%
    
或者使用
联合

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
如果您得到重复的行,您可能必须在
选择之后添加
DISTINCT

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

您可以使用
Left/Right
连接
internal
join返回两个表上存在的数据。感谢您的提示!但是既然我在语句中有两个连接,那么在给定的情况下,哪一个应该是哪一个?或者可能是完全联接的答案?您应该将它们都更改为
左联接
。这样,您将从
客户
交货地址
返回所有订单和相关数据。这是第一次收集,之后,使用``WHERE`子句,您可以筛选符合您条件的退货订单的结果。明白了–谢谢!在这种情况下,如果我将条件放在ON子句中,有什么区别?如果您在WHERE子句中设置条件c.first\U name(如“%max%”)和d.first\U name(如“%max%”),那么您实际上是在进行内部联接,因此您将只获得第一个\U名称在客户和交货地址中都匹配的订单,这不是您想要的。在您的情况下,您至少需要1个匹配项。这就是为什么WHERE子句中需要的唯一条件是
c.id不为NULL或d.customerId不为NULL
我不知道为什么,但我实现了这一点,没有移动所述的条件,而且它非常有效,即使与三个或四个不同的表组合,即使当时的技巧是使用不同的逻辑(或/和)当组合WHERE子句时。但是谢谢你的帮助!所有的评论和帖子都非常有助于我找到我需要去的地方。