Удалить частично повторяющиеся строки в SQL Server 2016 - PullRequest
3 голосов
/ 18 мая 2019

У меня есть набор данных, в котором есть некоторый столбец, в котором значения совпадают, но остальные значения столбца не совпадают. Мне нужно удалить дубликаты, где подкатегория более низкого уровня (уровень 2, уровень 3 и уровень 4) «НЕТ НЕДЕЙСТВИТЕЛЬНО», но соответствующий «дубликат партнера» (сгруппированный по [ID подкатегории уровня 1], [Категория продукта] и [Имя продукта] ) имеет ту же подкатегорию более низкого уровня - "IS NULL". В приведенной ниже таблице мне нужно удалить ID 2, 4, 6 и 9 (см. Выделено красным шрифтом).

Я пробовал функции Dense_Rank, Rank и Row_Number с Partition By, но это не дало мне нежелательный вывод. Может быть, мне нужно использовать их комбинацию ...

Например: RowID 1 и 2 являются дубликатами [Категория продукта], [Название продукта], [Категория уровня 1]. «Категория уровня 1» является просто идентификатором «Категория продукта». Необходимо удалить RowID 2, потому что соответствующему дублирующему партнеру RowID 1 не назначен «Категория уровня 3», когда RowID 2 имеет. Та же логика применима к RowID 9 и 10, но в это время RowID 9 имеет «Категория уровня 2», а строка 10 - нет. Если обоим дубликатам (RowID 1 и 2) будет присвоен «Уровень категории 3», нам не нужно удалять ни одного из них

Sample Dataset

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

1 Ответ

1 голос
/ 18 мая 2019

Если я правильно понимаю, ваша логика следующая:

Для каждой уникальной комбинации SubCategory Level 1, Product Category и Product Name вы хотите вернуть строку с наименьшим количеством заполненных данных уровня подкатегории.

Используя быстрые dense_rank с partitions в соответствующих полях, вы можете order строк с меньшим количеством подкатегорий установить на 1. Строки 2, 4, 6 и 9 теперь должны быть единственными возвращаемыми строками.

;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 1, Product Category и Product Name, они будут включены обе. Если вы не хотите этого, просто поменяйте местами dense_rank на row_number и добавьте несколько альтернативных критериев, по которым следует выбрать первый.

...