我有这个加入表:
CREATE TABLE [TagMap](
[intItemId] [bigint] NOT NULL,
[intTagId] [bigint] NOT NULL,
CONSTRAINT [PK_TagMap_intItemId] PRIMARY KEY CLUSTERED
(
[intItemId] ASC,
[intTagId] ASC
))
我的sproc发现了与seedItemId相关联的标签,然后选择与这些标签关联的其他intItemIds,如下所示:
declare @baseTags table (intTagId bigint primary key clustered);
INSERT INTO @baseTags (intTagId)
SELECT TOP 20 t1.intTagId
FROM TagMap t1
WHERE t1.intItemId = 776
SELECT TOP 500 t1.intItemId
FROM TagMap t1
JOIN @baseTags t2
ON t1.intTagId = t2.intTagId
GROUP BY t1.intItemId
ORDER BY Count(*) DESC
我需要指的是在两个intItemIds之间指定最小数量的标记关联 - 比方说10 - 低于该值不返回值。换句话说,在TagMap表中可以找到两个intItemId共有的十个或更多intTagId,它很好,我们选择它 - 否则忽略它。
所以,例如给出这个数据:
CREATE TABLE #TagMap(
[intItemId] [bigint] NOT NULL,
[intTagId] [bigint] NOT NULL,
CONSTRAINT [PK_TagMap_intItemId] PRIMARY KEY CLUSTERED
(
[intItemId] ASC,
[intTagId] ASC
))
insert into #TagMap
(intItemId, intTagId)
values
(1, 100),(1, 200),(1, 300),
(2, 100),(2, 200), (2, 500),(2, 600),
(3, 100), (3, 500),(3, 600)
假设匹配阈值为2。
如果种子是intItemId 1,则只返回intItemId 2(它有两个匹配的标记ID:100和200,而intItemId 3有一个:100,低于阈值)。
如果种子是intItemId 2,则应返回intItemId 1和3(intItemId 1匹配标记Ids 100和200,而intItemId 3匹配标记Ids 500和600)。
如果种子是intItemId 3,则只返回intItemId 2(它有两个匹配的标记ID:500和600,而intItemId有一个:100,低于阈值)。
请问如何做到这一点?
干杯, 马特
答案 0 :(得分:2)
SELECT
[foreign].intItemID
FROM
#TagMap AS [primary]
INNER JOIN
#TagMap AS [foreign]
ON [foreign].intTagID = [primary].intTagID
WHERE
[primary].intItemID = 1
GROUP BY
[foreign].intItemID
HAVING
COUNT(distinct [foreign].intTagID) >= @threshold
然而,请注意,这种情况非常糟糕;因为JOIN
搜索“ 任何 这些标记”,然后只能在HAVING
子句中指定“has 所有 这些标签“。
根据我的经验,您可以进行小的优化,但我找到的最有价值的方法是将结果缓存到更标准的映射表中。必要时更新它们。 (标签数据的内容很少变化。)
答案 1 :(得分:1)
这似乎是这样做的(将@InterestItem
改为1,2,3,它似乎产生了你要求的结果):
declare @InterestItem int
set @InterestItem = 1
declare @Threshold int
set @Threshold = 2
select
tm2.intItemId,
COUNT(*)
from
#TagMap tm1
inner join
#TagMap tm2
on
tm1.intTagId = tm2.intTagId and
tm2.intItemId <> tm1.intItemId
where
tm1.intItemId = @InterestItem
group by
tm2.intItemId
having
COUNT(*) >= @Threshold
我目前在结果集中包含COUNT
,但这不是必需的。