SQL Server:查询具有匹配标记的产品

时间:2018-02-02 01:28:48

标签: sql sql-server

过去几个小时我一直在思考这个问题,但我找不到解决办法。

我有一个表中的产品,另一个表中的标签和产品/标签链接表。 现在我想要检索所有与某个产品具有相同标签的产品。

以下是表格(简化):

产品

id varchar(36) (primary key)
Name varchar(50)

代码

id varchar(36) (primary key)
Name varchar(50)

PRODUCTTAG

id varchar(36) (primary key)
ProductID varchar(36)
TagID varchar(36)

我在Stackoverflow上找到了很多关于返回完整和部分匹配的答案。但是我正在寻找一个只提供完整匹配的查询。

示例:

Product A has tags 1, 2, 3
Product B has tags 1, 2
Product C has tags 1, 2, 3
Product D has tags 1, 2, 3, 4

如果我查询产品A,则只能找到产品C - 因为它是唯一具有完全相同标签的产品。

这甚至可能吗?

3 个答案:

答案 0 :(得分:0)

在这种情况下,我发现将所有标记组合成单个字符串并比较字符串更简单。但是,直到2016年,这在SQL Server中都很痛苦。

所以,有一个基于集合的解决方案:

with pt as (
      select pt.*, count(*) over (partition by productid) as cnt
      from producttag pt
     )
select pt.productid
from pt join
     pt pt2
     on pt.cnt = pt2.cnt and
        pt.productid <> pt2.productid and
        pt.tagid = pt2.tagid
where pt2.productid = @x
group by pt.productid, pt.cnt
having count(*) = pt.cnt;

这会根据标记将每个产品与您指定的产品相匹配。然后having子句确保两个产品的匹配标签数相同。由于join仅考虑匹配标记,因此所有标记都相同。

答案 1 :(得分:0)

是的,是的,请尝试这种方式:

x1: 60  y1: 217  x2: 83  y2: 288
x1: 60  y1: 169  x2: 83  y2: 216
x1: 60  y1: 217  x2: 83  y2: 288
x1: 60  y1: 169  x2: 83  y2: 216...

答案 2 :(得分:0)

declare @PRODUCTTAG table(id int identity(1,1),ProductID  int,TagID int)
insert into @PRODUCTTAG VALUES
(1,1),(1,2),(1,3)
,(2,1),(2,2)
,(3,1),(3,2),(3,3)
,(4,1),(4,2),(4,3),(4,4)

;With CTE as
(
select ProductID,count(*)smallCount 
FROM @PRODUCTTAG
group by ProductID
)
,CTE1 as
(
 select smallCount, count(smallCount)BigCount
 from cte
 group by smallCount
)
,CTE2 as
(
select * from cTE c
where exists(
select smallCount from cte1 c1
where BigCount>1 and c1.smallCount=c.smallCount
)
)

select * from cte2
--depending upon the output expected join this with @PRODUCTTAG,@Product,@Tag
--like this

--select * from @PRODUCTTAG PT
--where exists(
--select * from cte2 c2 where pt.productid=c2.productid
--)

或者告诉最终输出是什么样的?