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 - 使用正确的索引JOININTERSECT 应该与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的主要内容,如果未能解决你的问题,请参考以下文章

mssql可以远程连接吗?

如何扩展 Zend\Db\Sql\Select?

Oracle select with "in (multiple values)" 不使用索引

单元测试 react redux thunk dispatches with jest and react testing library for "v: 16.13.1",

Java通过jdbc连接DB2能使用with as( select ...吗

MS SQL 查询最后5条记录,该如何操作。