У меня есть две таблицы. Одним из них является CustomerOrders, а другим - OrderCustomerRef - таблица поиска.
Обе таблицы имеют отношение один ко многим - один клиент может быть связан с несколькими заказами.
В таблице CustomerOrders есть дубликаты клиентов (те же LName, FName, Email). Но у них разные Cust_ID.
Мне нужно объединить все дублирующиеся контакты в базовой таблице клиентов (один к одному). (эта таблица здесь не показана).
Шаг 1:
Необходимо выяснить, какой Cust_ID должен быть объединен с соответствующими дубликатами Клиента (тех же LName, FName, Email). Контакт с последней датой Order_Date должен победить своего дубликата (Клиента). Исключением будут VIP-клиенты - они всегда должны быть выигрышными, независимо от даты заказа.
Шаг 2: Обновленная таблица OrderCustomerRef: замените все проигрышные дубликаты Cust_ID на выигрышные Cust_ID.
Шаг 3: Удалить все потерянные контакты из базовой таблицы клиентов (нет в текущей области. Я сделаю это сам).
IF OBJECT_ID('tempdb..#table') IS NOT NULL
DROP TABLE #table;
IF OBJECT_ID('tempdb..#CustomerOrders') IS NOT NULL
DROP TABLE #CustomerOrders;
IF OBJECT_ID('tempdb..#OrderCustomerRef') IS NOT NULL
DROP TABLE #OrderCustomerRef;
CREATE TABLE #CustomerOrders
(
[PK_ID] INT NOT NULL PRIMARY KEY IDENTITY(1,1),
Cust_ID INT NOT NULL,
LName VARCHAR(100) NULL,
FName VARCHAR(100) NULL,
[Customer_E-mail] VARCHAR(100) NULL,
Order_Date DATETIME NULL,
Customer_Source VARCHAR(100) NULL,
CustomerType VARCHAR(100) NULL
)
INSERT INTO #CustomerOrders (Cust_ID, LName, FName, [Customer_E-mail], Order_Date, Customer_Source, CustomerType)
VALUES
(1, 'John', 'Smith', 'JSmith@email.com', '2018-11-10 01:40:55.150', 'XYZ Company', 'Regular'),
(2, 'John', 'Smith', 'JSmith@email.com', '2018-10-10 05:05:55.150', 'Internet', 'VIP'),
(3, 'Adam', 'Burns', 'ABurns@email.com', '2017-05-05 00:00:00.000', 'XYZ Company','Regular'),
(3, 'Adam', 'Burns', 'ABurns@email.com', '2017-05-05 00:00:00.000', 'XYZ Company','VIP'),
(4, 'Adam', 'Burns', 'ABurns@email.com', '2017-05-05 00:00:00.000', 'Internet','Regular'),
(5, 'Adam', 'Burns', 'ABurns@email.com', '2017-05-05 00:00:00.000', 'Internet','VIP'),
(6, 'James', 'Snatcher', 'JSnatcher@email.com', '2019-07-07 00:00:00.000', 'XYZ Company', 'Regular'),
(7, 'James', 'Snatcher', 'JSnatcher@email.com', '2019-07-07 00:00:00.000', 'Internet','Regular'),
(9, 'Thomas', 'Johnson', 'TJohnson@email.com', '2016-05-01 00:00:00.000', 'Internet','Regular'),
(9, 'Thomas', 'Johnson', 'TJohnson@email.com', '2015-04-01 00:00:00.000', 'Internet','Regular'),
(10, 'Thomas', 'Johnson', 'TJohnson@email.com', '2014-03-01 00:00:00.000', 'Internet','Regular'),
(11, 'Thomas', 'Johnson', 'TJohnson@email.com', '2013-02-01 00:00:00.000', 'XYZ Company','Regular'),
(12, 'Peter', 'McDonald', 'PMcDonald@email.com', '2013-02-01 00:00:00.000', 'XYZ Company','Regular'),
(13, 'Jose', 'Mainster', 'JMainster@email.com', '2013-02-01 00:00:00.000', 'Internet','Regular'),
(14, 'Kevin', 'Digginton', 'KDigginton@email.com', '2013-02-01 00:00:00.000', 'Internet','Regular'),
(14, 'Kevin', 'Digginton', 'KDigginton@email.com', '2015-09-03 00:00:00.000', 'Internet','Regular')
CREATE TABLE #OrderCustomerRef
(
Raw_PK INT NOT NULL PRIMARY KEY IDENTITY(1,1),
OrderID INT NOT NULL,
Cust_ID INT NULL,
OrderType VARCHAR(100) NULL
)
INSERT INTO #OrderCustomerRef (OrderID, Cust_ID, OrderType)
VALUES
(1,1,'Online'),
(2,2,'Online'),
(3,3,'Online'),
(4,3,'Online'),
(5,4,'In Store'),
(6,5,'Online'),
(7,6,'Online'),
(8,7,'In Store'),
(9,9,'Online'),
(10,9,'Online'),
(11,10,'In Store'),
(12,11,'Online'),
(13,12,'Online'),
(14,13,'Online'),
(15,14,'Online'),
(16,14,'In Store')
-- SELECT * FROM #OrderCustomerRef
SELECT *,
RANK() OVER (PARTITION BY FName, LName, [Customer_E-mail], Customer_Source ORDER BY Order_Date DESC) AS Rank_1,
RANK() OVER (PARTITION BY FName, LName, [Customer_E-mail], Customer_Source ORDER BY Order_Date, CustomerType DESC ) AS Rank_CustType,
RANK() OVER (PARTITION BY Cust_ID, FName, LName, [Customer_E-mail], Customer_Source ORDER BY Order_Date, CustomerType DESC ) AS Rank_CustID,
RANK() OVER (PARTITION BY FName, LName, [Customer_E-mail] ORDER BY Order_Date DESC) AS Rank_2,
RANK() OVER (PARTITION BY FName, LName, [Customer_E-mail] ORDER BY Cust_ID) AS Rank_3
FROM #CustomerOrders
НЕОБХОДИМЫЙ ВЫХОД ДОЛЖЕН СМОТРЕТЬ КАК:
* исключение: - потеря идентификаторов клиентов 1, 3 (должен быть выигрышным, но так как есть дубликат, это VIP, который он проигрывает) - выигрышные идентификаторы клиентов 2, 5 (потому что это VIP, за исключением)
Например: всеВхождения Cust_ID Джона Смита с Cust_ID 1 в ## OrderCustomerRef должны быть заменены на Джон Смит с Cust_ID 2 , все вхождения Cust_ID Адама Бернса с Cust_ID 3 должнызаменить на Адама Бернса с Cust_ID 5
общее правило: - потеря идентификаторов клиентов 7, 10, 11, 4 - выигрышные идентификаторы клиентов 6, 9, 12, 13, 14
Например: все вхождения Cust_ID 7 в ## OrderCustomerRef должны быть заменены на 6, все вхождения Cust_ID 10 должны быть заменены на 9 *
В конце концов у меня должны быть только идентификаторы клиентов 6, 9, 12, 13, 14, 2, 5 в ## OrderCustТаблица omerRef
Использование Rank_CustType_1, column_1, column_2 Я могу выяснить Шаг 1. Но у меня все еще есть проблема с Шагом 2 - обновление таблицы OrderCustomerRef как таковое: все проигравшие Cust_ID должны быть заменены соответствующим повторяющимся выигрышемCust_IDs.
Я пробовал это. Но это все еще не заменяет потерю Cust_ID.
SELECT *,
RANK() OVER (PARTITION BY FName, LName, [Customer_E-mail] ORDER BY Order_Date, CustomerType DESC) AS Rank_CustType_1,
RANK() OVER (PARTITION BY FName, LName, [Customer_E-mail] ORDER BY Cust_ID) AS Rank_3
INTO #table
FROM #CustomerOrders
; with cte as (
select Cust_ID, FName, LName, [Customer_E-mail], max(t.Rank_CustType_1) as Rank_CustType_1
,(select distinct Cust_ID from #table a where a.Cust_ID = t.Cust_ID and Rank_3 = 1) column_1
,(select distinct Cust_ID from #table a where a.Cust_ID = t.Cust_ID and Rank_3 <> 1) column_2
from #table t
group by Cust_ID, FName, LName, [Customer_E-mail]
)
update b
set Cust_ID = case
when b.Cust_ID = cte.Cust_ID and
b.Cust_ID = ISNULL(cte.column_1,'') and Rank_CustType_1 != 1 then b.Cust_ID
when b.Cust_ID = cte.Cust_ID and
b.Cust_ID = ISNULL(cte.column_2,'') and Rank_CustType_1 != 1 then cte.column_2
when b.Cust_ID = cte.Cust_ID and Rank_CustType_1 = 1 and cte.column_1 is null and cte.column_2 is not null then cte.column_2
when b.Cust_ID = cte.Cust_ID and Rank_CustType_1 = 1 and cte.column_1 is not null and cte.column_2 is null then cte.column_1
end
from #OrderCustomerRef b
inner join cte on b.Cust_ID = cte.Cust_ID;
select * from #OrderCustomerRef;