0

假设我有三张桌子。例如,一个表 (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 是特定的东西)并且应用了多个指定标签(例如,政治和科学)的行的最佳方法是什么?请注意,为此,我需要为每个选定的行提供所有指定的标签,而不是任何一个指定的标签。

我知道我可以通过选择先前选择的哪些结果适合另一个标签的条件来做到这一点,但是如果我选择多个标签,选择查询由于这种嵌套而变得越来越复杂,我相信必须有另一个,更简单的方法。

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

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

编辑: 所以,虽然来自 grayalien007 的答案对我不起作用,但它确实为我指明了正确的方向,这就是我最终使用的:

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

3 回答 3

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
于 2013-10-23T05:39:33.593 回答
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'
);
于 2013-10-23T08:33:15.517 回答
0

因此,虽然 grayalien007 的答案对我不起作用,但它确实为我指明了正确的方向,这就是我最终使用的:

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");
于 2013-10-23T13:47:31.943 回答