0

I'm having trouble tweaking a sql query that is returning duplicates. Its a simple query that returns data from a "wishlist". The structure of the wishlist is simple. 6 tables that feed into it:

Products - list of products, Images - list of images, Users - list of users, link_ProductsImages - links products to images, for one-to-many relationship (potentially), Wishlist - links users to products (and to images by proxy)

Here is some sample pretend data that sets up the following scenario. One user (100) has two products in his wishlist (1,2). ProductID 1 has one image associated with it (10), where ProductID 2 has three (11,12,13)

The goal is to have ONE LINE PER PRODUCT returned in the query. Because of the one-to-many of the products to images, Im getting duplicates returned on ProductID 2. Can someone help? I tried a few things I found on StackOverflow but I just can't seem to get the query ironed out.

Products ProductID - 1,2

Users UserID - 100

Images ImageID - 10, 11, 12, 13

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

Wishlist UserID, ProductID - 100, 1 100, 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
4

2 回答 2

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,所以如果你有ORDER BY i.ImageFile它会按字母顺序分配行号ImageFile。partition by 子句类似于GROUP BY并告诉行号函数每次在哪里重置为 0,因此在这种情况下PARTITION BY WishlistID确保行号对于每个愿望清单 ID 都是唯一的。最后,结果仅限于每个愿望清单 ID 的第一行,确保只返回一个图像。希望这能更清楚地说明情况。

于 2013-10-18T15:56:32.237 回答
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
于 2013-10-18T15:45:07.290 回答