首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SQL选择一个列的值在另一个标准列中常见的行

SQL选择一个列的值在另一个标准列中常见的行
EN

Stack Overflow用户
提问于 2009-09-10 22:54:03
回答 4查看 39K关注 0票数 14

我有一个交叉参考表,看起来是这样的:

代码语言:javascript
运行
复制
id  document_id  subject_id
1   8            21
2   5            17
3   5            76
4   7            88
5   9            17
6   9            76
7   2            76

它将文档与主题相匹配。文档可以是多个主题的成员。我想从这个表中返回行,在这个表中,给定的文档与给定集合中的主题所有匹配。例如,给定一组主题:

(17 76)

我只想返回与该集合中的所有主题匹配的文档行(至少)在交叉参考表的某个位置。给定上述集的期望输出集是:

代码语言:javascript
运行
复制
id  document_id  subject_id
2   5            17
3   5            76
5   9            17
6   9            76

注意,没有返回表的最后一行,因为该文档只匹配所需的主题之一。

在SQL中查询这个问题的最简单和最有效的方法是什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-09-10 23:16:24

我假设这个表的自然键是document_id + subject_id,id是代理项;IOW、document_id和subject_id是唯一的。因此,我将假装它不存在,并且自然键上有一个唯一的约束。

让我们从显而易见的开始。

代码语言:javascript
运行
复制
SELECT document_id, subject_id
  FROM document_subjects
 WHERE subject_id IN (17,76)

得到你想要的一切再加上你不想要的东西。所以我们要做的就是过滤掉其他的东西。“其他内容”是一组行,其计数不等于所需主题的计数。

代码语言:javascript
运行
复制
SELECT document_id
  FROM document_subjects
 WHERE subject_id IN (17,76)
 GROUP BY document_id
HAVING COUNT(*) = 2

请注意,subject_id被删除是因为它不参与分组。更进一步,我将添加一个名为subjects_i_want的假想表,它包含您想要的N行主题。

代码语言:javascript
运行
复制
SELECT document_id
  FROM document_subjects
 WHERE subject_id IN (SELECT subject_id FROM subjects_i_want)
 GROUP BY document_id
HAVING COUNT(*) = (SELECT COUNT(*) FROM subjects_i_want)

显然,可以将subjects_i_want替换为另一个子查询、临时表或其他什么。但是,一旦您有了这个document_id列表,就可以在更大的查询的子选择中使用它。

代码语言:javascript
运行
复制
SELECT document_id, subject_id, ...
  FROM document_subjects
 WHERE document_id IN(
        SELECT document_id
          FROM document_subjects
          WHERE subject_id IN (SELECT subject_id FROM subjects_i_want)
          GROUP BY document_id
         HAVING COUNT(*) = (SELECT COUNT(*) FROM subjects_i_want))

或者别的什么。

票数 29
EN

Stack Overflow用户

发布于 2015-06-09 20:04:31

使用Oracle (或任何允许with子句的数据库)。这允许精确地定义subject_id值一次。

代码语言:javascript
运行
复制
with t as (select distinct document_id from table1 where subject_id in (17,76) )
select document_id from table1 where subject_id in (select subject_id from t)
group by document_id 
having count(*) = (select count (*) from t);
票数 2
EN

Stack Overflow用户

发布于 2009-09-10 23:04:25

这是个很有趣的问题。

我假设您想要一个更一般化的查询,但是如果您总是有相同数量的主题(比如两个),我会这样做:

代码语言:javascript
运行
复制
 SELECT T.id, T.document_id, T.subject_id
   FROM table T
        INNER JOIN table T1 ON T.document_id = T1.document_id AND T1.subject_ID = 17
        INNER JOIN table T2 ON T.document_id = T2.document_id AND T2.subject_ID = 76            

当然,您还可以添加另一个内部联接来添加另一个主题ID。但我承认这不是一个很好的一般解决方案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1408141

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档