繁体   English   中英

SQL选择其中一列的值在另一条件列中相同的行

[英]SQL selecting rows where one column's value is common across another criteria column

我有一个交叉引用表,如下所示:

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)

我只想返回与该交叉引用表中某处(至少)匹配的所有主题的文档行。 给定上述设置的期望输出设置为:

id  document_id  subject_id
2   5            17
3   5            76
5   9            17
6   9            76

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

在SQL中最简单,最有效的查询方式是什么?

我假设此表的自然键是document_id + subject_id,并且该id是一个替代; IOW,document_id和subject_id是唯一的。 这样,我只是假装它不存在,并且唯一键在自然键上。

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

SELECT document_id, subject_id
  FROM document_subjects
 WHERE subject_id IN (17,76)

这样可以为您提供所有您想要的东西以及不需要的东西。 因此,我们需要做的就是过滤掉其他东西。 “其他内容”是行数不等于所需主题数的行组。

SELECT document_id
  FROM document_subjects
 WHERE subject_id IN (17,76)
 GROUP BY document_id
HAVING COUNT(*) = 2

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

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)

显然,subject_i_want可以换出另一个子查询,临时表或其他任何东西。 但是,一旦有了document_id的列表,就可以在较大查询的子选择中使用它。

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))

管他呢。

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

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);

这是一个非常有趣的问题。

我假设您想要一个更通用的查询,但这是在您始终具有相同数量的主题(例如两个)的情况下要做的:

 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            

当然,您可以添加另一个INNER JOIN来添加另一个主题ID。但是我承认这不是一个很好的常规解决方案。

select document_id from table1
 where subject_id in (17, 76)
 group by document_id
having count(distinct subject_id) = 2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM