2009-09-01 119 views
0

这应该是这么简单,但我画空白。我有两张桌子。看起来很简单,但我很难过!

Table:article_tag_pvt 
colum: article_id 
column: tag_id 

Table: tag 
column: tag_id 
column: name 

article_tag_pvt表是一个多对多的数据透视表。

问题是,我需要一个查询给出一个标签名称列表,它将检索只匹配那些标签名称的文章ID。基本这些表的加盟看起来是这样的:

SELECT article_id 
FROM article_tag_pvt pvt 
INNER JOIN tag t ON t.tag_id = pvt.tag_id 

我已经有一个查询将检索匹配指定的任何标签名称这文章的ID。这看起来是这样的:

SELECT article_id 
FROM article_tag_pvt pvt 
INNER JOIN tag t ON t.tag_id = pvt.tag_id 
WHERE t.name IN ('events','news') 

我已经试过这些,但没有喜悦:

SELECT article_id 
FROM article_tag_pvt pvt 
INNER JOIN tag t ON t.tag_id = pvt.tag_id 
WHERE t.name = 'events' AND t.name = 'news' 

SELECT article_id 
FROM article_tag_pvt pvt 
INNER JOIN (
SELECT tag_id 
FROM tag 
WHERE name IN ('events','news') 
) AS t 
ON t.tag_id = pvt.tag_id 

任何帮助,将不胜感激

戴夫

回答

3

问题是你得到的所有行都有事件或新闻。如果你从来没有超过1个事件或新闻在很多表中,你可以使用GROUP BY和HAVING来解决它

SELECT article_id 
FROM article_tag_pvt pvt 
INNER JOIN tag t ON t.tag_id = pvt.tag_id 
WHERE t.name = 'events' OR t.name = 'news' 
GROUP BY article_id HAVING count(*) = 2 
+0

现货,感谢您的迅速响应。 – 2009-09-01 01:50:37

2

我的选择是:

SELECT pvt.article_id 
    FROM article_tag_pvt pvt 
    JOIN tag t ON t.tag_id = pvt.tag_id AND t.name = 'events' 
    JOIN tag t2 ON t2.tag_id = pvt.tag_id AND t2.name = 'news' 

替代使用GROUP BY/HAVING:

SELECT pvt.article_id 
    FROM article_tag_pvt pvt 
    JOIN tag t ON t.tag_id = pvt.tag_id 
    WHERE t.name IN ('events', 'news') 
GROUP BY pvt.article_id, t.name 
    HAVING COUNT(DISTINCT t.name) = 2 

的COUNT(DISTINCT t.name)需要等于定义为t.name IN子句的选项的数量。

+0

感谢Rexem提供这些。在您的第二个解决方案中使用了Dimus的方法,计数工作不正确。标签的数量可能会变得很长,所以决定对多个连接。谢谢你的帮助。 – 2009-09-01 01:53:00