多对多关联表查询:获取未关联指定s_id的t_id
如何查询未关联s_id=1的t_id?
有t_model与s_model的多对多关联表t_id_s_id_table,表中数据如下:
| t_id | s_id |
|---|---|
| 1 | 1 |
| 1 | 2 |
| 2 | 2 |
| 2 | 3 |
| 3 | 1 |
| 3 | 3 |
需求是用单条SQL获取所有未关联s_id=1的t_id,预期结果仅为t_id=2。以下是两种无效尝试及最优解决方案:
无效查询分析
- 尝试1:
SELECT t_id FROM t_id_s_id_table WHERE NOT s_id = 1
结果会包含所有t_id(比如t_id=1、3虽然关联了s_id=1,但它们还有其他s_id的记录,这条语句会把这些记录的t_id也查出来),不符合预期。 - 尝试2:
SELECT t_id, JSON_ARRAYAGG(s_id) array FROM t_id_s_id_table GROUP BY t_id
能按t_id分组并聚合关联的s_id,但无法直接筛选出未关联s_id=1的t_id。
最优解决方案
方法1:GROUP BY + HAVING统计筛选
SELECT t_id FROM t_id_s_id_table GROUP BY t_id HAVING SUM(CASE WHEN s_id = 1 THEN 1 ELSE 0 END) = 0;
逻辑:按t_id分组后,统计每个t_id关联s_id=1的次数,次数为0的就是完全未关联s_id=1的t_id。
方法2:NOT EXISTS子查询
SELECT DISTINCT t_id FROM t_id_s_id_table t WHERE NOT EXISTS ( SELECT 1 FROM t_id_s_id_table WHERE t_id = t.t_id AND s_id = 1 );
逻辑:找出不存在对应t_id且s_id=1记录的t_id,用DISTINCT去重(因为关联表中一个t_id对应多条记录)。
方法3:LEFT JOIN + 空值筛选
SELECT DISTINCT t.t_id FROM t_id_s_id_table t LEFT JOIN t_id_s_id_table t1 ON t.t_id = t1.t_id AND t1.s_id = 1 WHERE t1.t_id IS NULL;
逻辑:将原表与自身关联(仅匹配s_id=1的记录),左关联后未匹配到的记录就是未关联s_id=1的,最后去重得到结果。
这三种方法都能得到预期结果,其中NOT EXISTS在数据量较大时性能通常更优(建议给t_id和s_id建立联合索引),GROUP BY + HAVING则更直观易懂。
内容的提问来源于stack exchange,提问作者user16012143
相关产品推荐
相关产品推荐

