从具有一对多关系的sql查询中删除重复返回

时间:2013-10-18 15:36:54

标签: sql sql-server tsql

我在调整返回重复项的SQL查询时遇到问题。它是一个从“愿望清单”返回数据的简单查询。愿望清单的结构很简单。 6张表格:

产品 - 产品列表,图像 - 图像列表,用户 - 用户列表,link_ProductsImages - 将产品链接到图像,一对多关系(可能),愿望清单 - 将用户链接到产品(以及通过代理)

以下是设置以下方案的一些示例假装数据。一个用户(100)在他的愿望清单(1,2)中有两个产品。 ProductID 1有一个与之关联的图像(10),其中ProductID 2有三个(11,12,13)

目标是在查询中返回一行产品。由于图像的一对多产品,我在ProductID 2上返回重复项。有人可以帮忙吗?我尝试了一些我在StackOverflow上找到的东西,但我似乎无法解决这个问题。

产品 ProductID - 1,2

用户 UserID - 100

图片 ImageID - 10,11,12,13

Link_ProductsImages ProductID,ImageID - 1,10 2,11 2,12 2,13

收藏 UserID,ProductID - 100,1100,2

  select w.WishlistID, p.*,
    isnull(i.ImageFile, 'na.jpg') as ImageFile
    from Products p
    inner join Wishlist w on w.UserID = 4 and w.ProductID = p.ProductID
    left outer join Link_ProductImage lpi on lpi.ProductID = p.ProductID
    left outer join Images i on i.ImageID = lpi.ImageID

2 个答案:

答案 0 :(得分:2)

您可以使用ROW_NUMBER()功能来优化图片,只需按照心愿单ID返回一个:

WITH CTE AS
(   SELECT  w.WishlistID, p.*,
            ImageFile = ISNULL(i.ImageFile, 'na.jpg'),
            ImageNumber = ROW_NUMBER() OVER(PARTITION BY w.WishListID ORDER BY NEWID())
    FROM    Products p
            INNER JOIN Wishlist w 
                ON w.UserID = 4 
                AND w.ProductID = p.ProductID
            LEFT JOIN Link_ProductImage lpi 
                ON lpi.ProductID = p.ProductID
            LEFT JOIN Images i 
                ON i.ImageID = lpi.ImageID
)
SELECT  *
FROM    CTE 
WHERE   ImageNumber = 1;

由于您没有给出任何优先处理图像的方法,我刚刚使用ORDER BY NEWID()随机选择了一个图像。如果您有选择图像的特定逻辑,则可以用逻辑替换它。

ROW_NUMBER函数基本上为每个图像分配每个心愿单ID中的等级,所以如果你有三个图像,它将分配1,2和3.它分配行号的方式是基于顺序,所以如果你已ORDER BY i.ImageFile它会按ImageFile的字母顺序分配行号。 partition by子句类似于GROUP BY,并告诉行号函数每次重置为0的位置,因此在这种情况下PARTITION BY WishlistID确保每个wishlist ID的行号都是唯一的。最后,结果仅限于每个心愿单ID的第一行,确保只返回一个图像。希望这会对情况有所了解。

答案 1 :(得分:0)

也许你的意思是:

SELECT DISTINCT w.WishlistID, p.*,
isnull(i.ImageFile, 'na.jpg') as ImageFile
from Products p
inner join Wishlist w on w.UserID = 4 and w.ProductID = p.ProductID
left outer join Link_ProductImage lpi on lpi.ProductID = p.ProductID
left outer join Images i on i.ImageID = lpi.ImageID