sql:多对多关系和all子句

pgx2nnw8  于 2021-06-18  发布在  Mysql
关注(0)|答案(1)|浏览(359)

我有一张table products 还有一张table locations 它们以多对多的关系与一个表链接在一起 products_locations . 现在,客户机可以选择一组产品,我想运行一个查询,只选择所有选定产品都可用的位置。
一开始这看起来很直截了当,但我发现自己对如何实现这一点感到困惑。我一开始以为我可以得到所有正确的位置标识

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,两个位置都有效。

js5cn81o

js5cn81o1#

我找到了一个能满足我需要的查询。虽然它不像我所希望的那样干净,但它似乎是一种强有力的方法来解决我试图质疑的问题:

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 .
我选择 location_id (s) 从那张临时table上 t ,其中点击数等于用户选择的产品数。如果这个数字比较低,我知道至少有一个产品不匹配的位置。

相关问题