[英]SQL: many-to-many relationship and the 'ALL' clause
I have a table products
and a table locations
which are linked together in a many-to-many relationship with a table products_locations
. 我有一个表products
和一张桌子locations
,其在一个表中的许多一对多的关系联系在一起products_locations
。 Now a client can select a set of products, and I want to run a query that selects only the locations, where ALL of the selected products are available. 现在,客户可以选择一组产品,我想运行一个只选择所有选定产品的位置的查询。
This seemed pretty straight forward at first, but I see myself being quite baffled by how to achieve this. 起初这看起来很简单,但我发现自己对如何实现这一点感到非常困惑。 I initially thought I could get all the correct location-ids with something like 我最初认为我可以用类似的东西获得所有正确的位置ID
SELECT location_id
FROM products_locations
WHERE product_id = ALL [the user selected product ids]
But on second thought that does not appear to make sense either (the structure of products_locations
is quite simply [product_id, location_id]
. 但是第二种想法似乎也没有意义( products_locations
的结构很简单[product_id, location_id]
。
Any suggestion on how to structure such a query would be appreciated. 任何有关如何构建此类查询的建议都将受到赞赏。 I feel like I am overlooking something basic.. 我觉得我忽略了一些基本的东西..
EDIT: I am using mysql
syntax/dialect 编辑:我使用的是mysql
语法/方言
Quick sample: Given the following 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 |
|--------------------------|
If a user selects products 1 and 2, the query should return only location 2. If the user selects products 2 and 3, the query should return location 1. For 1, 2, and 3, no location would be valid, and for product 2, both locations would be valid. 如果用户选择产品1和2,则查询应仅返回位置2.如果用户选择产品2和3,则查询应返回位置1.对于1,2和3,没有位置有效,对于产品2,两个地点都有效。
I figured out a query that achieves what I need. 我想出了一个能够实现我需要的查询。 Though it is not as clean as I had hoped, it seems to be a robust approach to what I'm trying to query: 虽然它不像我希望的那样干净,但它似乎是我正在尝试查询的一种强有力的方法:
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];
Explanation: 说明:
t
which contains every location_id
that has at least one matching product in the user's selection, together with the number of times that location matches a product in the user's selection. 我创建了一个临时表t
,其中包含每个location_id
,其中包含用户选择中至少一个匹配产品,以及该位置与用户选择中的产品匹配的次数。 This is achieved by grouping the query by location_id
. 这是通过按location_id
对查询进行分组来实现的。 location_id
(s) from that temporary table t
, where the number of hits is equal to the number of products the user had selected. 我从该临时表t
选择location_id
,其中命中数等于用户选择的产品数。 If that number is lower, I know that at least one product did not match that location. 如果该数字较低,我知道至少有一个产品与该位置不匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.