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

如何查询数据库表中包含指定所有类型的记录?

检索包含全部指定类型的记录的最优SQL方案

嘿,这个需求我经常遇到,咱们可以用几种高效的SQL写法来实现,刚好结合你的例子(要找包含A、B、C全部类型的记录)给你拆解一下:

方法1:GROUP BY + HAVING COUNT(最经典高效)

这是最常用的方案,适合大多数场景,尤其是当你有name和type的联合索引时,性能会非常好。假设你的表名为records,字段是name(记录名称)和type(类型):

SELECT name
FROM records
WHERE type IN ('A', 'B', 'C')  -- 先过滤出目标类型相关的行
GROUP BY name
HAVING COUNT(DISTINCT type) = 3;  -- 确保分组包含全部3种目标类型

逻辑解释:

  • WHERE子句先筛掉和目标类型无关的行,减少后续计算量;
  • GROUP BY name把同一记录的所有类型行聚合到一起;
  • HAVING COUNT(DISTINCT type) = 3确保这个分组里刚好包含3种不同的目标类型(因为我们要的是A、B、C全部存在)。

对应你的例子:

  • "First"记录的分组过滤后有A、B、C,COUNT结果是3,符合条件;
  • "Second"记录的分组只有A、B,COUNT结果是2,被排除。

方法2:多EXISTS子查询(适合类型数量少的场景)

如果你的目标类型数量不多,或者需要返回记录的其他字段而不想用GROUP BY,可以用多个EXISTS来逐一验证每个类型是否存在:

SELECT DISTINCT r.name
FROM records r
WHERE EXISTS (SELECT 1 FROM records r1 WHERE r1.name = r.name AND r1.type = 'A')
  AND EXISTS (SELECT 1 FROM records r1 WHERE r1.name = r.name AND r1.type = 'B')
  AND EXISTS (SELECT 1 FROM records r1 WHERE r1.name = r.name AND r1.type = 'C');

逻辑解释:

每个EXISTS子查询都会检查当前记录是否包含对应的类型,只有当三个条件全部满足时,这条记录才会被选中。用DISTINCT是因为一条记录可能对应多个type行,避免重复返回。

方法3:窗口函数(适合需要返回完整记录的场景)

如果你需要返回记录的所有字段,而不仅仅是name,可以用窗口函数来统计每个记录的目标类型数量:

WITH filtered_records AS (
  SELECT 
    *,
    COUNT(DISTINCT type) OVER (PARTITION BY name) AS target_type_count
  FROM records
  WHERE type IN ('A', 'B', 'C')
)
SELECT DISTINCT *  -- 返回所有字段,DISTINCT去重
FROM filtered_records
WHERE target_type_count = 3;

逻辑解释:

  • 先通过CTE给每个记录(按name分组)计算符合目标类型的数量;
  • 然后筛选出数量等于目标类型数的记录,再去重得到最终结果。

最优方案选择

  • 如果只需要返回记录名称(或分组字段),GROUP BY + HAVING是最优选择,性能最高;
  • 如果目标类型数量很少(比如3个以内),EXISTS子查询的可读性更好,性能也不错;
  • 如果需要返回完整的记录字段,窗口函数的写法更灵活,不需要额外处理分组后的字段聚合。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:01:51