2012-02-14 62 views
2

我真的不知道如何解释,除了“垂直在哪里”。MSSQL选择“垂直” - 其中

想象一下如下表:

TAGID|PRODUCTID|SHOP_ID 
59 |3418-7 |38 
61 |3418-7 |38 
60 |4227-4 |38 
61 |4227-4 |38 

现在我要回全部产品ID,具有相对于标签ID:59,61。换句话说,这两行的标签ID的行存在的产品ID值。

所以我想回到3418-7,但不4227-4

如何在SQL语句写这篇尽可能简单?

这是工作的语句我到目前为止,但我觉得这可能更智能的方式来完成:

SELECT 
    productid 
FROM shop_tag_relations 
WHERE 
    productid IN (select productid from shop_tag_relations WHERE tagid=59) 
AND 
    productid IN (select productid from shop_tag_relations WHERE tagid=61) 
GROUP BY productid,shop_id 
+0

这是什么意思? “所有产品ID,与标签有关系:59,61” – YXD 2012-02-14 12:41:09

+0

返回与tagid 59和61有关的产品。这是一张关系表,它描绘一张表中的产品和另一张表中的标签之间的关系。例如,如果3418是男士的棕色鞋,标签59可能是鞋,标签61可能是男士,72棕色等。 – Esben 2012-02-14 12:45:08

回答

8
SELECT PRODUCTID 
FROM T 
WHERE TAGID IN (59,61) 
GROUP BY PRODUCTID 
HAVING COUNT(DISTINCT TAGID) = 2 

或者

SELECT PRODUCTID 
FROM T 
WHERE TAGID = 59 
INTERSECT 
SELECT PRODUCTID 
FROM T 
WHERE TAGID = 61 
+0

该版本的+1版本:Portable AND快速 – 2012-02-14 12:47:34

+0

@EugenRieck - 使用正确的索引时,JOIN或INTERSECT应该比GROUP BY更快或更快。它们扩展起来不方便。 – 2012-02-14 12:49:43

+1

INTERSECT的可移植性比GROUP BY少得多,JOIN比GROUP BY复杂得多,包含更多标签 - 因此在一天结束时GROUP BY是我认为最佳的解决方案 – 2012-02-14 12:52:27

2
SELECT DISTINCT 
a.PRODUCTID 
FROM mytable AS a 
INNER JOIN mytable AS b ON a.PRODUCTID=b.PRODUCTID 
WHERE a.TAGID=59 
AND b.TAGID=61 
; 
+0

这可行,但如果它是10 tagid而不是2呢? – Esben 2012-02-14 12:43:30

+1

此问题的每个解决方案都有缩放问题(您的初始解决方案,我的答案)或不可移植(相交)。选择你的毒药。要点是,JOIN解决方案将由查询规划器进行高度优化,TAGID上是否有索引。 – 2012-02-14 12:47:11

+0

感谢您的澄清 – Esben 2012-02-14 12:48:54

1
SELECT ProductId 
FROM shop_tag_relations 
WHERE TAGID IN (59,61) 
GROUP BY ProductId 
HAVING COUNT(DISTINCT TagId) = 2