You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL多对多关系查询:如何筛选恰好匹配指定关联项及数量的记录

多对多关联下精确匹配桶内水果组合的查询方案

核心校验逻辑

要筛出刚好只装了2个苹果、1根香蕉、没有其他额外水果的桶,三个判定条件必须同时满足,缺一个都可能返回错误结果:

  • 桶内的水果品类总数刚好是2种,不存在苹果、香蕉之外的其他水果
  • 桶里必须同时有苹果和香蕉,不能缺任意一种
  • 两种水果的数量完全对得上:苹果2个,香蕉1个

通用SQL实现(兼容绝大多数关系型数据库)

这个写法不依赖任何数据库特有的函数,逻辑严谨可以直接复用,基于题目给出的表结构和示例数据编写:

SELECT b.id, b.name
FROM Buckets b
INNER JOIN Bucket_Fruit bf 
  ON b.id = bf.bucket_id
WHERE 
  -- 先过滤出和目标水果+对应数量匹配的关联记录
  (bf.fruit_id = (SELECT id FROM Fruits WHERE name = 'Apple') AND bf.count = 2)
  OR (bf.fruit_id = (SELECT id FROM Fruits WHERE name = 'Banana') AND bf.count = 1)
GROUP BY b.id, b.name
HAVING
  -- 校验1:桶里实际装的总品类数就是2种,直接排除多装了其他水果的桶
  (SELECT COUNT(*) FROM Bucket_Fruit bf_total WHERE bf_total.bucket_id = b.id) = 2
  -- 校验2:苹果、香蕉两个品类都在桶里,没有缺漏
  AND COUNT(*) = 2
  -- 校验3:两个品类的存储数量完全匹配要求
  AND SUM(CASE WHEN bf.fruit_id = (SELECT id FROM Fruits WHERE name = 'Apple') THEN bf.count ELSE 0 END) = 2
  AND SUM(CASE WHEN bf.fruit_id = (SELECT id FROM Fruits WHERE name = 'Banana') THEN bf.count ELSE 0 END) = 1;

简洁写法(适配支持字符串聚合的数据库,比如MySQL、PostgreSQL)

题目里已经给了业务规则兜底:不存在两个桶的水果存储品类、数量完全一致,这种情况下可以用聚合拼接的方式简化代码,查询效率更高:

-- MySQL版本示例
SELECT b.id, b.name
FROM Buckets b
INNER JOIN Bucket_Fruit bf ON b.id = bf.bucket_id
GROUP BY b.id, b.name
HAVING GROUP_CONCAT(CONCAT(bf.fruit_id, ':', bf.count) ORDER BY bf.fruit_id) = '1:2,2:1';

这个写法的逻辑很直接:把每个桶里所有「水果ID:对应数量」的组合按固定顺序拼接成字符串,和目标组合拼出来的字符串做精确相等判断,只要字符串完全一致,就说明桶里的水果品类、数量完全符合要求,不会多装也不会少装。

注意:拼接的时候必须加ORDER BY固定拼接顺序,不然数据库返回记录的顺序是随机的,可能出现内容一样但顺序不对导致匹配失败的问题。

内容的提问来源于stack exchange,提问作者vitech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 14:27:18