【问题标题】:Remove Partial Duplicate Rows in SQL Server 2016删除 SQL Server 2016 中的部分重复行
【发布时间】:2019-10-05 06:51:15
【问题描述】:

我有一个数据集,其中包含一些值匹配的列,但其余列值不匹配。我需要删除较低级别(Level2、Level3 和 Level 4)的子类别“不为空”但其相应的“重复伙伴”(按 [SubCategory Level 1 ID]、[Product Category] ​​和 [Product Name] 分组)的重复项) 具有相同的较低级别子类别 - “IS NULL”。根据下表,我需要删除 ID 2、4、6 和 9(见红色字体突出显示)。

我已经尝试使用 Partition By 的 Dense_Rank、Rank 和 Row_Number 函数,但这并没有给我不想要的输出。也许我需要使用它们的组合...

例如:RowID 1 和 2 与 [Product Category]、[Product Name]、[Category Level 1] 重复。 “Category Level 1”只是“Product Category”的一个ID。需要删除 RowID 2,因为其对应的重复伙伴 RowID 1 没有在 RowID 2 具有时分配“类别级别 3”。相同的逻辑适用于第 9 行和第 10 行,但此时第 9 行具有“类别级别 2”,而第 10 行没有。如果两个重复项(RowID 1 和 2)都分配了“Category Level 3”,我们就不需要删除它们中的任何一个

IF OBJECT_ID('tempdb..#Category', 'U') IS NOT NULL
  DROP TABLE #Category;
GO

CREATE TABLE #Category 
(
    RowID INT NOT NULL,
    CategoryID INT NOT NULL,
    ProductCategory VARCHAR(100) NOT NULL,
    ProductName VARCHAR(100) NOT NULL,
    [SubCategory Level 1 ID] INT NOT NULL,
    [SubCategory Level 2 ID] INT NULL,
    [SubCategory Level 3 ID] INT NULL,  
    [SubCategory Level 4 ID] INT NULL
);

INSERT INTO #Category (RowID, CategoryID, ProductCategory, ProductName, [SubCategory Level 1 ID], [SubCategory Level 2 ID], [SubCategory Level 3 ID], [SubCategory Level 4 ID])
VALUES 
(1, 111, 'Furniture', 'Table', 200, 111, NULL, NULL),
(2, 234, 'Furniture', 'Table', 200, 234, 123, NULL),
(3, 122, 'Furniture', 'Chair', 200, 122, NULL, NULL),
(4, 122, 'Furniture', 'Chair', 200, 122, 32, NULL),
(5, 12, 'Auto', 'Trucks', 300, 766, 12, NULL),
(6, 3434, 'Auto', 'Trucks', 300, 322, 3434, 333),
(7, 332, 'Auto', 'Sport Vehicles', 300, 332, NULL, NULL),
(8, 332, 'Auto', 'Sport Vehicles', 300, 332, NULL, NULL),
(9, 300, 'Auto', 'Sedans', 300, 231, NULL, NULL),
(10, 300, 'Auto', 'Sedans', 300, NULL, NULL, NULL),
(11, 300, 'Auto', 'Cabriolet', 300, 456, 688, NULL),
(12, 300, 'Auto', 'Cabriolet', 300, 456, 976, NULL),
(13, 300, 'Auto', 'Motorcycles', 300, 456, 235, 334),
(14, 300, 'Auto', 'Motorcycles', 300, 456, 235, 334);


SELECT * FROM #Category; 
-- ADD YOU CODE HERE TO RETURN the following RowIDs: 2, 4, 6, 9

【问题讨论】:

  • 请显示您现有的查询
  • 您的要求很难理解。您能解释一下为什么要删除 2、4、6 和 9 吗?
  • 嗨 Forpas,出于同样的原因,它们应该被删除。例如:RowID 1 和 2 按 [Product Category]、[Product Name]、[Category Level 1] 重复。 “Category level 1”只是“Product Category”的一个ID。需要删除 RowID 2,因为它的对应伙伴 RowID 1 没有在 RowID 2 有时分配“类别级别 3”。 RowID 9 和 10 的逻辑相同,但此时 RowID 9 具有“Category Level 2”,而 RowID 10 没有。如果两个重复项(RowID 1 和 2)都分配了“Category Level 3”,我们就不需要删除它们中的任何一个。

标签: sql-server group-by duplicates partitioning dense-rank


【解决方案1】:

如果我理解正确,您的逻辑如下:

对于每个唯一的SubCategory Level 1Product CategoryProduct Name 组合,您希望返回子类别级别数据填充量最少的行。

在相关字段上使用带有partitions 的快速dense_rank,您可以将order 具有较少子类别级别的行设置为12469 行现在应该是唯一返回的行。

;with DataToSelect
as
(
    SELECT *,
           DENSE_RANK() OVER(PARTITION BY [ProductCategory], [ProductName], [SubCategory Level 1 ID] 
                    ORDER BY
                        CASE 
                            WHEN [SubCategory Level 4 ID] IS NOT NULL THEN 3
                            WHEN [SubCategory Level 3 ID] IS NOT NULL THEN 2
                            WHEN [SubCategory Level 2 ID] IS NOT NULL THEN 1
                            END) as [ToInclude]
    FROM #Category
)
SELECT *
FROM 
    DataToSelect
WHERE 
    ToInclude != 1
ORDER BY 
    RowID

请记住,如果每个 SubCategory Level 1Product CategoryProduct Name 组合的子类别级别相同的两行,它们都会被包括在内。如果您不想这样做,只需将 dense_rank 交换为 row_number 并添加一些应首先选择的替代标准。

【讨论】:

  • 嗨,马特,我已经尝试过这种方法,这不是我想要实现的。正如我所说,我只需要第 2、4、6 和 9 行。逻辑 si 删除所有重复(类别 1,类别名称和产品名称)记录,其中较低级别类别在一个或多个重复项中不为 NULL,但其中一个重复行未分配相同的较低级别类别(IS NULL) .所以我会只保留一行分配了更高级别的类别而没有较低级别(见上面的截图。它具有相同的确切模式)
  • 你的查询返回 RowIDs - 1, 3, 6, 7, 8 and 10
  • 好的,你的问题很不清楚。如果您只想要行 2,4,6,9,那么我只是将 where 子句换成了 !=。为什么要接收重复行而不是非重复行?
  • 马特,我确实用一个回答你问题的例子更新了我的代码。此外,当切换到“ToInclude !=1”时,返回 RowID 2、4、5 和 9。我们不应该删除 RowID 5。但确实需要删除重复的 Row_ID 6,因为它具有“分配的类别级别 4”(333)。因此,您可以看到它仅适用于 Category Level 2 和“Level 3”而不适用于“Category Level 4”。
  • 马特,你很亲密。我们还需要如下扭曲 CASE 语句 WHEN [SubCategory Level 4 ID] IS not NULL THEN 3 WHEN [SubCategory Level 3 ID] IS not NULL THEN 2 WHEN [SubCategory Level 2 ID] IS not NULL THEN 1 我更新了你的代码.非常感谢!
猜你喜欢
  • 2019-12-04
  • 2017-11-16
  • 1970-01-01
  • 2012-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-25
相关资源
最近更新 更多