SQL:多对多关系和“ALL”子句

Posted

技术标签:

【中文标题】SQL:多对多关系和“ALL”子句【英文标题】:SQL: many-to-many relationship and the 'ALL' clause 【发布时间】:2018-09-26 09:49:49 【问题描述】:

我有一个表 products 和一个表 locations,它们以多对多关系与表 products_locations 链接在一起。现在客户可以选择一组产品,我想运行一个查询,只选择所有选定产品都可用的位置。

起初这似乎很简单,但我发现自己对如何实现这一点感到很困惑。我最初认为我可以使用类似

的东西获得所有正确的位置ID
SELECT location_id
FROM products_locations
WHERE product_id = ALL [the user selected product ids]

但仔细想想,这似乎也没有意义(products_locations 的结构很简单[product_id, location_id]

任何有关如何构建此类查询的建议都将不胜感激。我觉得我忽略了一些基本的东西..

编辑:我正在使用mysql 语法/方言

快速示例:给定下表

| products   | | locations | | products_locations       |
| id | name  | | id | name | | product_id | location_id |
|------------| |-----------| |--------------------------|
| 1  | prod1 | | 1  | locA | | 1          | 2           |
| 2  | prod2 | | 2  | locB | | 2          | 1           |
| 3  | prod3 | |-----------| | 2          | 2           |
|------------|               | 3          | 1           |
                             |--------------------------|

如果用户选择产品 1 和 2,则查询应仅返回位置 2。如果用户选择产品 2 和 3,则查询应返回位置 1。对于 1、2 和 3,没有任何位置有效,对于产品 2,这两个位置都有效。

【问题讨论】:

您使用的是哪个DBMS 产品? “SQL”只是一种查询语言,而不是特定数据库产品的名称。请为您正在使用的数据库产品添加tag postgresql, oracle, sql-server, db2, ... 添加一些示例表数据和预期结果。开始之前先看看***.com/help/mcve。 我使用 mysql 作为方言,我将它添加到原始问题中。我的错,我忘了指定 @jarlh 你是对的,我错误地省略了一个例子,因为害怕混淆读者,我现在添加了一个,因为我能够把它归结起来。谢谢! 【参考方案1】:

我想出了一个可以满足我需要的查询。虽然它不像我希望的那样干净,但它似乎是我试图查询的一种强大的方法:

SELECT t.location_id
FROM (SELECT location_id, COUNT(*) as n_hits
      FROM products_locations
      WHERE product_id IN [the user selected products]
      GROUP BY location_id) t
WHERE n_hits = [the number of user selected products];

解释:

    我创建了一个临时表t,其中包含在用户选择中至少有一个匹配产品的每个location_id,以及该位置与用户选择中的产品匹配的次数。这是通过将查询按location_id 分组来实现的。 我从该临时表t 中选择location_id(s),其中点击数等于用户选择的产品数。如果该数字较低,我知道至少有一种产品与该位置不匹配。

【讨论】:

以我自己的方式找到了同样问题的解决方案。之后,找到了你的解决方案。也许这是唯一的解决方案,或者我们认为是平等的。

以上是关于SQL:多对多关系和“ALL”子句的主要内容,如果未能解决你的问题,请参考以下文章

多对多关系的jpa标准

未找到列:Laravel 5 多对多关系查询中“on 子句”中的 1054 未知列“managers.id”

SQL Server Analysis Services 中的多对多关系;第二个多对多关系不起作用

具有多对多关系的核心数据 - 在 SUBQUERY 中使用 ALL 创建 NSPredicate

MS SQL 使用联结表创建多对多关系

用户-角色多对多查询sql