简体   繁体   English

如何使用最右边的表过滤多对多左连接?

[英]How to filter a many-to-many left join using the rightmost table?

Suppose I have the following tables:假设我有以下表格:

Machine机器

| id | name    |
+----+---------+
| 1  | Blender |
| 2  | Slicer  |
| 3  | Masher  |

Part部分

| id | name            | instock |
+----+-----------------+---------+
| 1  | Blade           | 5       |
| 2  | Rotating engine | 0       |
| 3  | Plug            | 10      |
| 4  | Wire            | 10      |

MachinePart (many-to-many) MachinePart (多对多)

| mid | pid |
+-----+-----+
| 1   | 1   |
| 1   | 2   |
| 1   | 3   |
| 1   | 4   |
| 2   | 1   |
| 2   | 3   |
| 2   | 4   |

I want a single query to list all machines with parts (outer joined), as long as the part is in stock .我想要一个查询来列出所有带有零件(外连接)的机器,只要零件有库存

I have tried doing the condition in the LEFT JOIN, but then the middle table generates an unwanted record:我尝试在 LEFT JOIN 中执行条件,但中间表生成了不需要的记录:

SELECT m.id, m.name, mp.pid, p.name, p.instock
  FROM machine m
  LEFT JOIN machinepart mp ON mp.mid = m.id
  LEFT JOIN part p ON p.id = mp.pid AND instock > 0

| id | name    | pid  | name  | instock |
+----+---------+------+-------+---------+
| 1  | Blender | 1    | Blade | 5       |
| 1  | Blender | 2    | NULL  | NULL    |  -> I don't want this record
| 1  | Blender | 3    | Plug  | 10      |
| 1  | Blender | 4    | Wire  | 10      |
| 2  | Slicer  | 1    | Blade | 5       |
| 2  | Slicer  | 3    | Plug  | 10      |
| 2  | Slicer  | 4    | Wire  | 10      |
| 3  | Masher  | NULL | NULL  | NULL    |  -> But good, I want this record

How do I filter machinepart based on a field in the related table part ?如何根据相关表part中的字段过滤machinepart

If it matters, I'm using PostgreSQL.如果重要的话,我正在使用 PostgreSQL。 (but I assume the solution will be generic) (但我认为解决方案将是通用的)

WHERE P.INSTOCK IS NOT NULL

You can also get all of the "out of stock" parts with IS NULL instead您也可以使用IS NULL来获取所有“缺货”零件

edit: I didn't see you DO want results for machines with no parts (because neither "part is out of stock" nor "part is in stock" make sense for a machine with no parts?)编辑:我没有看到您确实想要没有零件的机器的结果(因为“零件缺货”或“零件有货”对于没有零件的机器都没有意义?)

WHERE P.INSTOCK IS NOT NULL
OR MP.PID IS NULL

edit2: <2nd suggestion won't work either> edit2:<第二个建议也不起作用>

I think you want an INNER JOIN and then a LEFT JOIN :我想你想要一个INNER JOIN然后一个LEFT JOIN

SELECT m.id, m.name, mp.pid, p.name, p.instock
FROM machine m INNER JOIN
     machinepart mp
     ON mp.mid = m.id LEFT JOIN
     part p
     ON p.id = mp.pid AND p.instock > 0;

EDIT:编辑:

This produces the results that you request:这会产生您要求的结果:

SELECT m.id, m.name, mp.pid, p.name, p.instock
FROM machine m LEFT JOIN
     machinepart mp
     ON mp.mid = m.id LEFT JOIN
     part p
     ON p.id = mp.pid 
WHERE (p.instock > 0 OR p.instock IS NULL);

Here is a db<>fiddle. 是一个 db<>fiddle。

Seems like unusual logic, though.不过,这似乎是不寻常的逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM