(SQL)选择具有2个与其关联的特定值的行

时间:2013-10-23 04:08:25

标签: c# sql sqlite select system.data.sqlite

假设我有三张桌子。一个表(TblArticles)描述了例如文章。它有一个自动递增键,文章名称和有关它的其他数据,例如:

pkIndex | sName | Other Data...
--------|-------|--------------
   1    | Name1 | Data1
   2    | Name2 | Data2
   3    | Name3 | Data3

等等。然后我有一个标签表(TblTags),例如:

pkIndex | sName
--------|--------
   1    | Politics
   2    | Science
   3    | Fun

等等。我有一个关系表(TblArticlesTagsRel),因为一篇文章可以有多个标签,每个标签可以应用于多个文章:

indArticle | indTag
-----------|-------
     1     |   1
     1     |   2
     2     |   1
     2     |   3
     3     |   3

等等。

所以,我的问题是,从TblArticles中选择适合某些条件的行的最佳方法是什么(比如sName是特定的)并且应用了几个指定的标签(例如,Politics和Science)?请注意,为此,我需要为每个选定的行提供所有指定的标记,而不是任何一个指定的标记。

我知道我可以通过选择前一个选择的哪个结果符合另一个标签的条件来做到这一点,但如果我选择多个标签,那么选择查询会变得越来越复杂,因为这种嵌套我相信它有成为另一种更容易的方式。

我尝试过以各种方式使用AND,但在这种情况下我无法弄清楚如何使用它。

哦,如果这很重要,我正在使用SQLite。

修改 所以,虽然greyalien007的答案对我不起作用,但它确实指出了我正确的方向,这就是我最终使用的:

SELECT a.* FROM TblArticles a, (SELECT indArticle FROM TblArticlesTagsRel WHERE indTag IN(1,2) GROUP BY indArticle HAVING COUNT(indArticle)=2) WHERE (a.pkIndex = indArticle) AND (sName = "title");

3 个答案:

答案 0 :(得分:1)

我不确定SQLite支持什么,但是如果它确实派生了像tsql这样的表..

这是我设置您的数据:

create table TblArticles (pkIndex int, sName varchar(100))
create table TblTags(pkIndex int, sName varchar(100))
create table TblArticlesTagsRel (indArticle int, indTag int)

insert into TblArticles(pkIndex, sName)
values
   (1, 'Name1')
,  (2, 'Name2')
,  (3, 'Name3')

insert into TblTags(pkIndex, sName)
values
   (1, 'Science')
,  (2, 'Politics')
,  (3, 'Fun')

insert into TblArticlesTagsRel(indArticle, indTag)
values
  (1, 1)
, (1, 2)
, (2, 1)
, (2, 3)
, (3, 3)

我试图解决这个问题:

select a.*
from TblArticles a
inner join (
    select indArticle, count(indArticle) as 'tagCount'
    from TblArticlesTagsRel r
        inner join TblTags t on r.indTag = t.pkIndex
where t.sName in ('Politics', 'Science')
group by indArticle
) d on a.pkIndex = d.indArticle
where sName = 'Name1' and tagCount = 2

答案 1 :(得分:0)

未优化,但应该完成工作:

SELECT * FROM TblArticles WHERE sName="title" AND
EXISTS (
    SELECT * FROM TblArticlesTagsRel
    JOIN TblTags ON TblTags.pkIndex=TblArticlesTagsRel.indTag
    WHERE TblArticlesTagsRel.indArticle=TblArticles.pkIndex AND
    TblTags.sName='Politics'
) AND EXISTS (
    SELECT * FROM TblArticlesTagsRel
    JOIN TblTags ON TblTags.pkIndex=TblArticlesTagsRel.indTag
    WHERE TblArticlesTagsRel.indArticle=TblArticles.pkIndex AND
    TblTags.sName='Science'
);

答案 2 :(得分:0)

所以,虽然greyalien007的答案对我不起作用,但它确实指出了我正确的方向,这就是我最终使用的内容:

select * from TblArticles,
(
   select indArticle from TblArticlesTagsRel
   where indTag IN(1, 2) 
   group by indArticle  
   having count(indArticle) = 2
)
where (pkIndex = indArticle) 
and (sName = "title");