0

我有一张表,其中产品与图片进行映射。有些产品与图片有 1 到 n 个映射。为了很好地查看映射,我构建了一个 SQL,以便可以按 ProductId 分组查看它们。

    SELECT  [Id]
      ,[ProductId]
      ,[PictureId]
      ,[DisplayOrder]
FROM [LandOgFritid23].[dbo].[Product_Picture_Mapping]
Where ProductId in (select ProductId
                    FROM [LandOgFritid23].[dbo].Product p,
                    [LandOgFritid23].[dbo].[Product_Picture_Mapping] pm
                    where p.Id = pm.ProductId
                    group by ProductId
                    having COUNT(pm.PictureId) > 3
                    )
order by ProductId

结果:

Id  ProductId   PictureId   DisplayOrder
2085    103    2388         2
2185    103    2488         1
7132    103    7468         1
7133    103    7469         1
2158    107    2461         0
320     107    415          1
3485    107    3816         1
3486    107    3817         1
3529    107    3860         1

现在,要求每个产品只允许 3 张图片 MAX。我发现很难创建一个 DELETE 语句来删除产品的第 4、5、n 个映射的任何行。

如果可能的话,你有什么想法吗?

所以删除后的结果,这个数据将是:

Id  ProductId   PictureId   DisplayOrder
2085    103    2388         2
2185    103    2488         1
7132    103    7468         1
2158    107    2461         0
320     107    415          1
3485    107    3816         1

谢谢

4

2 回答 2

5

使用 CTE:

注意:假设您要保留最新的 3 张图片

WITH Data AS
(
    SELECT  *, 
            ROW_NUMBER() 
             OVER(PARTITION BY ProductId ORDER BY PictureId DESC) 
            AS Position
     FROM [LandOgFritid23].[dbo].[Product_Picture_Mapping]
 )
 DELETE 
    FROM Data
 WHERE Position > 3
于 2012-07-07T14:11:23.083 回答
1

您可以使用 ROW_NUMBER() 按 PictureId 分区并按适当字段排序来确定前三个记录。

请注意,我在这里假设您使用 DisplayOrder 字段以降序来确定排序:

SELECT *
FROM (
    SELECT  [Id]
          ,[ProductId]
          ,[PictureId]
          ,[DisplayOrder]
          , ROW_NUMBER() OVER (PARTITION BY ProductId ORDER BY DisplayOrder DESC) as PicNum
    FROM [LandOgFritid23].[dbo].[Product_Picture_Mapping]
    Where ProductId in (select ProductId
                        FROM [LandOgFritid23].[dbo].Product p,
                        [LandOgFritid23].[dbo].[Product_Picture_Mapping] pm
                        where p.Id = pm.ProductId
                        group by ProductId
                        having COUNT(pm.PictureId) > 3
                        )
) x
WHERE x.PicNum <= 3
ORDER BY ProductId, PicNum

我猜你正在做一个单独的查询来获取所有包含三张或更少图片的产品?您可以在一个查询中完成整个操作,只需删除 WHERE 子句和子查询:

SELECT *
FROM (
    SELECT  [Id]
          ,[ProductId]
          ,[PictureId]
          ,[DisplayOrder]
          , ROW_NUMBER() OVER (PARTITION BY ProductId ORDER BY DisplayOrder DESC) as PicNum
    FROM [LandOgFritid23].[dbo].[Product_Picture_Mapping]
) x
WHERE x.PicNum <= 3
ORDER BY ProductId, PicNum
于 2012-07-07T14:28:35.117 回答