繁体   English   中英

INNER JOIN SQL 查询包含重复项

[英]INNER JOIN SQL query includes duplicates

我有一个在线商店,我想在产品页面上显示五个类似的产品。 我尝试使用INNER JOIN查询(连接表)的产品和标签之间存在多对多关系。 这是我迄今为止的 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)

我想排除重复项。 到目前为止,我已经尝试过DISTINCTGROUP BY ,正如不同问题中的其他回答所显示的那样,但无济于事。 SELECT后添加DISTINCT时收到的错误是...

如果指定了 SELECT DISTINCT,则 ORDER BY 项必须出现在选择列表中。

有什么建议?

您可以按产品分组并按匹配标签的数量对结果进行排序:

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;

如果我正确地跟随您,您可以将逻辑移动到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 个搜索标签的产品。

如果没有这样的标签,您的代码可以返回与任何标签都不匹配的五个产品。 我不知道这是功能还是错误。 根据查询的描述,这听起来像是一个错误。

您需要每个产品 ID 一行。 我猜你真的不需要匹配的标签。 如果没有,最简单的方法是使用INEXISTS过滤掉不匹配的产品:

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)
             );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM