MSSQL Select with "vertical"-where
Posted
技术标签:
【中文标题】MSSQL Select with "vertical"-where【英文标题】: 【发布时间】:2012-02-14 12:37:32 【问题描述】:我真的不知道如何解释,除了“垂直位置”。
想象一下下表:
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
【问题讨论】:
这是什么意思? “所有与 tagid 相关的产品 ID:59,61” 返回与 tagid 59 和 61 相关的 productid。这是一个关系表,它绘制一个表中的产品和另一个表中的标签之间的关系。例如,如果 3418 是男士棕色鞋,标签 59 可能是鞋子,标签 61 可能是男士,72 棕色等等。 【参考方案1】: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
【讨论】:
@EugenRieck - 使用正确的索引JOIN
或INTERSECT
应该与GROUP BY
一样快或更快。它们只是不太方便扩展。
INTERSECT 的可移植性比 GROUP BY 差得多,JOIN 比 GROUP BY 复杂得多,标签更多 - 所以归根结底,我认为 GROUP BY 是最佳解决方案【参考方案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
;
【讨论】:
此问题的每个解决方案都存在缩放问题(您的初始解决方案,我的回答)或不可移植(相交)。选择你的毒药。关键是,查询计划器将高度优化 JOIN 解决方案,TAGID 上是否有索引。【参考方案3】:SELECT ProductId
FROM shop_tag_relations
WHERE TAGID IN (59,61)
GROUP BY ProductId
HAVING COUNT(DISTINCT TagId) = 2
【讨论】:
以上是关于MSSQL Select with "vertical"-where的主要内容,如果未能解决你的问题,请参考以下文章
Oracle select with "in (multiple values)" 不使用索引
单元测试 react redux thunk dispatches with jest and react testing library for "v: 16.13.1",