SQL:多对多关系和 'ALL' 子句
SQL: many-to-many relationship and the 'ALL' clause
我有一个 table products
和一个 table locations
它们以多对多的关系链接在一起 table products_locations
。现在客户可以 select 一组产品,我想 运行 查询 select 只有位置,所有 selected 产品都可用。
起初这似乎很简单,但我发现自己对如何实现这一点感到很困惑。我最初以为我可以通过
之类的东西获得所有正确的位置 ID
SELECT location_id
FROM products_locations
WHERE product_id = ALL [the user selected product ids]
但转念一想这似乎也没有意义(products_locations
的结构非常简单 [product_id, location_id]
.
任何有关如何构建此类查询的建议都将不胜感激。我觉得我忽略了一些基本的东西..
编辑:我正在使用 mysql
syntax/dialect
快速示例:给定以下 tables
| 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 |
|--------------------------|
如果用户 select 的产品 1 和 2,查询应该 return 只有位置 2。如果用户 select 的产品 2 和 3,查询应该 return 位置 1。对于 1、2 和 3,没有位置有效,对于产品 2,两个位置都有效。
我找到了一个可以满足我需要的查询。虽然它不像我希望的那样干净,但对于我要查询的内容来说,它似乎是一种可靠的方法:
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];
解释:
- 我创建了一个临时 table
t
,其中包含每个 location_id
在用户的 selection 中至少有一个匹配产品,以及次数该位置与用户 selection 中的产品相匹配。这是通过按 location_id
. 对查询进行分组来实现的
- I select 来自临时 table
t
的 location_id
(s),其中点击数等于用户拥有的产品数 select编辑。如果该数字较低,我知道至少有一种产品与该位置不匹配。
我有一个 table products
和一个 table locations
它们以多对多的关系链接在一起 table products_locations
。现在客户可以 select 一组产品,我想 运行 查询 select 只有位置,所有 selected 产品都可用。
起初这似乎很简单,但我发现自己对如何实现这一点感到很困惑。我最初以为我可以通过
之类的东西获得所有正确的位置 IDSELECT location_id
FROM products_locations
WHERE product_id = ALL [the user selected product ids]
但转念一想这似乎也没有意义(products_locations
的结构非常简单 [product_id, location_id]
.
任何有关如何构建此类查询的建议都将不胜感激。我觉得我忽略了一些基本的东西..
编辑:我正在使用 mysql
syntax/dialect
快速示例:给定以下 tables
| 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 |
|--------------------------|
如果用户 select 的产品 1 和 2,查询应该 return 只有位置 2。如果用户 select 的产品 2 和 3,查询应该 return 位置 1。对于 1、2 和 3,没有位置有效,对于产品 2,两个位置都有效。
我找到了一个可以满足我需要的查询。虽然它不像我希望的那样干净,但对于我要查询的内容来说,它似乎是一种可靠的方法:
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];
解释:
- 我创建了一个临时 table
t
,其中包含每个location_id
在用户的 selection 中至少有一个匹配产品,以及次数该位置与用户 selection 中的产品相匹配。这是通过按location_id
. 对查询进行分组来实现的
- I select 来自临时 table
t
的location_id
(s),其中点击数等于用户拥有的产品数 select编辑。如果该数字较低,我知道至少有一种产品与该位置不匹配。