在JOIN中从MySQL查询中排除结果


Exclude result from MySQL query in JOIN

我有多个包含订单和交货的表,我只想得到未结订单(只想得到交货表中没有记录的订单)。

所以,我的表格看起来像:

订单表(sh_comenzi):

id  partner
1   Partner X
2   Partner Y
3   Partner Z
4   Partner Q

订单行表(sh_comenzi_pos),其中idcsh_comenzi表的id

id  idc cPos    quantity
1   1   1       5
2   1   2       10
3   1   3       20
4   2   1       10
5   2   2       15
6   3   1       10
7   3   2       5
8   3   3       8
9   4   1       15

交货项目表为(sh_delivery_items)

id  idc cPos
1   1   1
2   1   3
3   2   2
4   3   1
5   3   2
6   3   3

想要的结果应该会给我一个未结订单的输出,就像这样:

id  partner
1   Partner X
2   Partner Y
4   Partner Q

结果不必跟踪数量,只需在线水平上即可。如果sh_delivery_items中存在订单中的一行,则该行将关闭。

我试过这样的东西:

SELECT DISTINCT sh_comenzi.id, partner FROM sh_comenzi
LEFT JOIN sh_comenzi_pos ON sh_comenzi.id = sh_comenzi_pos.idc
LEFT JOIN sh_delivery_items ON (sh_comenzi_pos.idc = sh_delivery_items.idc AND sh_comenzi_pos.cPos = sh_delivery_items.cPos)
WHERE sh_comenzi.id IS NOT NULL
ORDER BY sh_comenzi.id DESC

有人能帮我吗?

这是您需要的查询:

SELECT DISTINCT c.*
FROM sh_comenzi c
  INNER JOIN sh_comenzi_pos p
      ON c.id = p.idc
  LEFT JOIN sh_delivery_items di               # 'di' from 'delivery items'
      ON p.idc = di.idc AND p.cPos = di.cPos
WHERE di.id IS NULL                            # keep only not-delivered items

它的工作原理

它将所有订单(表sh_comenzi)及其行项目(表sh_comenzi_pos)组合在一起。INNER JOIN将省略空订单(如果有的话);如果需要,请使用LEFT JOIN

接下来,使用一对列(idccPos)将每一行(订单、行项目)与递送信息(表sh_delivery_items)组合。LEFT JOIN确保左侧表(或结果集)中的所有行都出现在最终结果集中;如果右侧表中的一行找不到与左侧表中的行相匹配的行,则使用一行充满NULLs的行。这种情况发生在尚未交付的行项目上(sh_delivery_items中没有它们的记录)。

然后,WHERE子句只保留di表(sh_delivery_items)中具有NULLs的行,即未交付的行项目,以及拥有它们的订单。

最后,SELECT DISTINCT c.*只从订单表(sh_comenzi)中选择列,DISTINCT确保每个订单只出现一次。否则,对于每个未交付的行项目,每个订单都会显示一次。

使用所需的ORDER BY子句自己完成查询。