多对多查询

joh*_*nyx 2 mysql sql

我有两个表产品和多个关系的部分和一个连接表products_sections.产品可以是一个或多个部分(新的,汽车的,飞机的,旧的).

Products
id    name
-----------------
1     something
2     something_else
3     other_thing


Sections
id    name
-----------------
1     new
2     car

Products_sections
product_id     section_id
--------------------------
1              1
1              2
2              1
3              2
Run Code Online (Sandbox Code Playgroud)

我想提取新车和汽车部分的所有产品.在此示例中,返回的结果应该是产品1.获取此信息的正确mysql查询是什么?

Ste*_*ass 6

SELECT Products.name
FROM Products
WHERE NOT EXISTS (
  SELECT id
  FROM Sections
  WHERE name IN ('new','car')
  AND NOT EXISTS (
    SELECT *
    FROM Products_sections
    WHERE Products_sections.section_id = Sections.id
    AND Products_sections.product_id = Products.id
  )
)
Run Code Online (Sandbox Code Playgroud)

换句话说,选择那些产品的Products_sections表中没有缺少所需的Section.id值的产品.

回答andho的评论:

你可以放

  NOT EXISTS (<select query>)
Run Code Online (Sandbox Code Playgroud)

像任何其他谓词一样进入WHERE子句.如果<select query>描述的结果集中没有行,它将评估为TRUE.

逐步地,这里是如何得到这个查询作为答案:

步骤1.要求是识别"在'新'和'汽车'部分中的所有产品".

步骤2.如果"新"和"汽车"部分都包含产品,则产品在"新"和"汽车"部分.同样地,如果这些部分都不能包含产品,则产品同时位于"新"和"汽车"部分.(注意双重否定: 不能包含.)再次重申,我们希望所有没有必需部分的产品不能包含产品.

所需的部分是这些:

SELECT id
FROM Sections
WHERE name IN ('new','car')
Run Code Online (Sandbox Code Playgroud)

因此,所需的产品是:

SELECT Products.name
FROM Products
WHERE NOT EXISTS ( -- there does not exist
  SELECT id  -- a section
  FROM Sections
  WHERE name IN ('new','car') -- that is required
   AND (the section identified by Sections.id fails to contain the product identified by Products.id)
)
Run Code Online (Sandbox Code Playgroud)

步骤3.如果给定部分和特定产品的Products_sections中有一行,则给定部分(例如"new"或"car")确实包含特定产品.因此,如果Products_sections中没有这样的行,则给定的部分不能包含特定的产品.

步骤4.如果下面的查询确实包含一行,则section_id部分确实包含product_id产品:

SELECT *
FROM Products_sections
WHERE Products_sections.section_id = Sections.id
AND Products_sections.product_id = Products_id
Run Code Online (Sandbox Code Playgroud)

因此,如果上面的查询在结果中没有产生行,或者如果不是EXISTS(),则section_id部分无法包含产品(这就是我们需要表达的内容).

看起来很复杂,但是一旦你掌握了它,它就会坚持:是否所有必需的物品都存在?是的,只要不存在不存在的必需项目.