SQL多表查询:筛选含指定全部关键词或单个关键词的文档
嘿,这个需求其实很好实现,我给你两种实用的思路,你可以根据自己的实际数据量和维护需求来选择:
实现思路与具体代码
方法一:分组统计筛选法
这种方法的核心是先筛选出我们关心的目标词汇,然后按文档分组,通过统计每个文档包含的指定词汇数量来判断是否符合条件。
具体SQL代码如下:
WITH TargetWords AS ( SELECT IdWord, Word FROM @TableA WHERE Word IN ('A', 'B', 'C', 'E') ) SELECT DISTINCT b.Document FROM @TableB b JOIN TargetWords w ON b.IdWord = w.IdWord GROUP BY b.Document HAVING -- 满足同时包含A、B、C三个词汇 (COUNT(CASE WHEN w.Word IN ('A','B','C') THEN 1 END) = 3) -- 或者包含E这个词汇 OR MAX(CASE WHEN w.Word = 'E' THEN 1 ELSE 0 END) = 1;
代码说明:
- 先用
WITH子句创建一个临时的TargetWords表,只保留我们需要查询的词汇(A、B、C、E),减少后续关联的数据量。 - 关联
TableB和TargetWords,拿到所有包含目标词汇的文档记录。 - 按
Document分组后,通过HAVING子句判断两种情况:- 统计该文档包含A/B/C的数量是否为3(意味着三个词汇都存在);
- 检查该文档是否包含E(用MAX函数判断是否有符合的记录)。
- 用
DISTINCT确保同一个文档只返回一次,避免因为多条词汇记录导致重复结果。
方法二:子查询+存在判断法
这种方法逻辑更直观,直接通过EXISTS子查询来判断每个文档是否满足条件,可读性很强,适合数据量不大的场景。
具体SQL代码如下:
SELECT DISTINCT Document FROM @TableB b WHERE -- 情况1:文档同时包含A、B、C三个词汇 EXISTS (SELECT 1 FROM @TableB b1 WHERE b1.Document = b.Document AND b1.IdWord = (SELECT IdWord FROM @TableA WHERE Word='A')) AND EXISTS (SELECT 1 FROM @TableB b2 WHERE b2.Document = b.Document AND b2.IdWord = (SELECT IdWord FROM @TableA WHERE Word='B')) AND EXISTS (SELECT 1 FROM @TableB b3 WHERE b3.Document = b.Document AND b3.IdWord = (SELECT IdWord FROM @TableA WHERE Word='C')) -- 情况2:文档包含E这个词汇 OR EXISTS (SELECT 1 FROM @TableB b4 WHERE b4.Document = b.Document AND b4.IdWord = (SELECT IdWord FROM @TableA WHERE Word='E'));
代码说明:
- 对
TableB中的每个文档,分别用EXISTS检查:- 是否存在该文档对应的A词汇记录;
- 是否存在该文档对应的B词汇记录;
- 是否存在该文档对应的C词汇记录;
这三个条件同时满足,就符合“包含所有A、B、C”的要求。
- 再用
OR连接“是否存在E词汇记录”的判断,满足任意一种情况就返回该文档。 - 同样用
DISTINCT去重,保证结果唯一。
两种方法的适用场景
- 如果你的数据量较大,建议优先使用方法一,配合
TableB上的(Document, IdWord)组合索引,查询效率会更高; - 如果更看重代码的可读性和易维护性,方法二会更友好,逻辑一目了然,后续修改条件也很方便。
内容的提问来源于stack exchange,提问作者Pedro
相关产品推荐
相关产品推荐

