过去几个小时我一直在思考这个问题,但我找不到解决办法。
我有一个表中的产品,另一个表中的标签和产品/标签链接表。 现在我想要检索所有与某个产品具有相同标签的产品。
以下是表格(简化):
产品:
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 - 因为它是唯一具有完全相同标签的产品。
这甚至可能吗?
答案 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
--)
或者告诉最终输出是什么样的?