MySQL 左连接多个表和 where 子句

标签 mysql left-join right-join

我尝试了很多组合,所以也许我只是做错了。嗯,我肯定做错了。

我知道 Stack Overflow 上总是要求提供代码,但这会混淆问题,因为我的代码现在已转变为另一种语言。

困惑:

有两个 WHERE 子句,无论我将其放在哪里,我要么收到错误,要么 JOIN 不起作用

问题:

我有 4 张 table :

customers - 即使没有付款,我也需要返回所有行,但前提是customer_status = 1

payments - 包含链接到 customers 表的 customer_id - 仅当 payment_status = 1

branches - 包含链接到customers表的customer_id

managers - 包含链接到branches表的branch_id

CUSTOMER    |    TOTAL_RECEIVED    |    BRANCH      |    MANAGER_NAME
----------------------------------------------------------------------
Pepsi       |    £1000             |    London      |    Mr Smith
Coca Cola   |                      |    Manchester  |    Mr Beckham
Dr Pepper   |    £2500             |    Shanghai    |    Mr Miagi
Duff        |                      |    Springfield |    Mr Simpson

如您所见,coca cola 和 duff 尚未付款(付款表中没有记录),但仍应列出

  • 因此,如果 customer_status = 1,客户应该全部出现
  • SUM 仅当付款在数据库中并且 payment_status = 1
  • 分支机构和经理应列出该客户,因为该客户始终位于数据库中
  • 经理位于自己的表格中,因为有很多并且在不同时间分配给不同的分支机构(因为我感觉有人可能会问)

所选字段及其摘要

c.customer_id, c.customer_companyname, c.customer_status FROM customers c WHERE c.customer_status = 1

SUM(p.payment_amount) as total_received, p.customer_id, p.payment_status FROM payments p WHERE p.payment_status = 1

b.branch_id, b.branch, b.customer_id FROM branches b WHERE b.customer_id = c.customer_id

m.manager_id, m.manager_name, m.branch_id FROM managers m WHERE m.branch_id = b.branch_id

最佳答案

解决这个问题的关键是将付款条件放入连接条件中:

SELECT 
    c.customer_id,
    c.customer_companyname,
    c.customer_status,
    SUM(p.payment_amount) as total_received,
    b.branch_id,
    b.branch,
    m.manager_id,
    m.manager_name
FROM customers c
LEFT JOIN payments p on p.customer_id = c.customer_id
  AND p.payment_status = 1 -- Payment condition here!
LEFT JOIN branches b ON b.customer_id = c.customer_id
LEFT JOIN managers m ON m.branch_id = b.branch_id
WHERE c.customer_status = 1
GROUP BY
    c.customer_id,
    c.customer_companyname,
    c.customer_status,
    b.branch_id,
    b.branch,
    m.manager_id,
    m.manager_name

两个要点:

  • 您无法在 WHERE 子句中设置付款条件的原因是,错过的联接在联接列中存在空值,因此对付款状态的测试不会为真,您将通过以下方式过滤掉没有付款的客户状态 1,而不是如果总和返回 0。通过将条件放入连接条件中,它只匹配合适的行,但仍然允许返回没有任何行的客户行。
  • 连接条件中可以包含非关键相关条件。大多数人没有意识到这一点。记住这一点很好。

请注意,您的加入条件看起来不正确。我希望分支应该与 c.branch_id = b.brach_id 匹配,经理也类似,但我会将其留给您来解决。

关于MySQL 左连接多个表和 where 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24025823/

相关文章:

mysql - 错误: ER_BAD_FIELD_ERROR: Unknown column 'kappa' in 'where clause'

php - MySQL 内部连接返回同一行的倍数

sql - 如何在 Doctrine 中像右连接一样使用左连接

mysql - mysql用户定义函数字符集的问题

从数据库表中解析 PHP SQL 数据给出错误 `Trying to get property of non-object`

mysql - SQL Left/Inner/Normal Join vs Where while 条件语句

mysql - LEFT JOIN 和 COUNT 两个查询的区别

找不到行时 MYSQL 左连接不工作

mysql - Cakephp 的 SQL JOIN 查询

mysql - SELECT 与 DIFFTIME 相关的问题