INNER JOIN SQL 查询包含重复项
INNER JOIN SQL query includes duplicates
我有一个在线商店,我想在产品页面上显示五个类似的产品。我尝试使用 INNER JOIN
查询(加入 table)的产品和标签之间存在多对多关系。这是我到目前为止的 SQL 查询:
SELECT TOP(5) *
FROM [Store_ProductTags] AS [s]
INNER JOIN [Store_Products] AS [s0] ON [s].[ProductId] = [s0].[Id]
ORDER BY CASE WHEN TagId IN (1, 17) THEN 0 ELSE 1 END;
它做我想做的事情(即获得五个与正在展示的产品具有相同标签的产品),但是,包括重复项...
这是我得到的结果(注意 ProductId 为 1 的两条记录):
ProductId TagId Name
10 17 Harlots - The Woman You Saw... (CD)
1 1 Unholy - Blood of the Medusa (CD)
44 1 Unholy - Blood of the Medusa (LP)
1 2 Unholy - Blood of the Medusa (CD)
2 2 Lye By Mistake - Arrangements for Fulminating Vective (CD)
我想排除重复项。到目前为止,我已经尝试了 DISTINCT
和 GROUP BY
,正如不同问题中的其他回复所显示的那样,但无济于事。我在 SELECT
之后添加 DISTINCT
时收到的错误是...
ORDER BY items must appear in the select list if SELECT DISTINCT is
specified.
有什么建议吗?
您可以按产品分组并按匹配标签的数量对结果进行排序:
SELECT TOP(5) p.Id, p.Name
FROM Store_Products AS p INNER JOIN Store_ProductTags AS s
ON s.ProductId = p.Id
GROUP BY p.Id, p.Name
ORDER BY SUM(CASE WHEN s.TagId IN (1, 17) THEN 1 ELSE 0 END) DESC;
如果没有此类标签,您的代码可以 return 五个不匹配任何标签的产品。我不知道这是功能还是错误。根据查询的描述,这听起来像是一个错误。
每个产品 ID 一行。我猜你真的不需要匹配的标签。如果不是,最简单的方法是使用 IN
或 EXISTS
:
过滤掉不匹配的产品
SELECT TOP(5) sp.*
FROM Store_Products sp
WHERE EXISTS (SELECT 1
FROM Store_ProductTags spt
WHERE spt.[ProductId] = s.[Id] AND
spt.TagId IN (1, 17)
);
如果我没听错,你可以将逻辑移动到 order by
子句中的子查询:
select top (5) p.*
from store_products p
order by
case when exists (
select 1
from store_producttags pt
where pt.productid = p.id and pt.tagid in (1, 17)
)
then 0
else 1
end
这将选择 5 个产品,并优先考虑拥有 2 个搜索标签的产品。
我有一个在线商店,我想在产品页面上显示五个类似的产品。我尝试使用 INNER JOIN
查询(加入 table)的产品和标签之间存在多对多关系。这是我到目前为止的 SQL 查询:
SELECT TOP(5) *
FROM [Store_ProductTags] AS [s]
INNER JOIN [Store_Products] AS [s0] ON [s].[ProductId] = [s0].[Id]
ORDER BY CASE WHEN TagId IN (1, 17) THEN 0 ELSE 1 END;
它做我想做的事情(即获得五个与正在展示的产品具有相同标签的产品),但是,包括重复项...
这是我得到的结果(注意 ProductId 为 1 的两条记录):
ProductId TagId Name
10 17 Harlots - The Woman You Saw... (CD)
1 1 Unholy - Blood of the Medusa (CD)
44 1 Unholy - Blood of the Medusa (LP)
1 2 Unholy - Blood of the Medusa (CD)
2 2 Lye By Mistake - Arrangements for Fulminating Vective (CD)
我想排除重复项。到目前为止,我已经尝试了 DISTINCT
和 GROUP BY
,正如不同问题中的其他回复所显示的那样,但无济于事。我在 SELECT
之后添加 DISTINCT
时收到的错误是...
ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
有什么建议吗?
您可以按产品分组并按匹配标签的数量对结果进行排序:
SELECT TOP(5) p.Id, p.Name
FROM Store_Products AS p INNER JOIN Store_ProductTags AS s
ON s.ProductId = p.Id
GROUP BY p.Id, p.Name
ORDER BY SUM(CASE WHEN s.TagId IN (1, 17) THEN 1 ELSE 0 END) DESC;
如果没有此类标签,您的代码可以 return 五个不匹配任何标签的产品。我不知道这是功能还是错误。根据查询的描述,这听起来像是一个错误。
每个产品 ID 一行。我猜你真的不需要匹配的标签。如果不是,最简单的方法是使用 IN
或 EXISTS
:
SELECT TOP(5) sp.*
FROM Store_Products sp
WHERE EXISTS (SELECT 1
FROM Store_ProductTags spt
WHERE spt.[ProductId] = s.[Id] AND
spt.TagId IN (1, 17)
);
如果我没听错,你可以将逻辑移动到 order by
子句中的子查询:
select top (5) p.*
from store_products p
order by
case when exists (
select 1
from store_producttags pt
where pt.productid = p.id and pt.tagid in (1, 17)
)
then 0
else 1
end
这将选择 5 个产品,并优先考虑拥有 2 个搜索标签的产品。