2015-11-12 94 views
1

我正在清理電子商務網站上的客戶列表。客戶列表在客戶ID和客戶電子郵件之間具有多對多的關係。例如,客戶可以在登錄或匿名時使用同一電子郵件下訂單,結果將是具有相同電子郵件但不同客戶ID的兩個客戶記錄。同樣,客戶可以在登錄時使用兩個不同的電子郵件創建訂單,這將導致具有相同ID但不同電子郵件的客戶記錄。鑑於此,我想根據電子郵件或客戶編號創建具有真正唯一ID的客戶列表。此外,在某些情況下,電子郵件是空白的,因此客戶記錄都有空白的電子郵件,但不同的ID需要被視爲兩個不同的客戶。SQL Server:根據兩列生成唯一的客戶密鑰

所以給出這樣的事情:

CUST_ID CUST_EMAIL 
------------------------ 
123  [email protected] 
123  [email protected] 
124  [email protected] 
125  [email protected] 
126 
127 
128  [email protected] 
128  [email protected] 
129  [email protected] 

我會想產生這樣一個關鍵:

CUST_ID CUST_EMAIL  NEW_CUST_KEY 
------------------------------------ 
123  [email protected]  1 
123  [email protected]  1 
124  [email protected]  2 
125  [email protected]  2 
126       3 
127       4 
128  [email protected]  5 
128  [email protected]  5 
129  [email protected]  5 
+0

這是一次性轉換還是可以在不改變現有數據的情況下重現的?我假定基於第一句話進行轉換,那麼爲什麼不在'WHILE'循環中做到這一點。然後,您可以與之前的記錄進行比較,看看是否需要新ID。 – Steve

+0

我將需要每天運行此操作以合併新的客戶記錄,但只要記錄分組正確,爲給定客戶生成的密鑰是否每天都會發生變化並不重要。我很可能每天都會截斷並重新加載目標表,所以任何可用作一次轉換的東西都應該沒問題。 – EvanMPW

+0

就WHILE循環而言,我不認爲只和前一個記錄進行比較是可行的。如果您查看上述示例中的最後一條記錄,如果您之前將其與記錄進行比較,則看起來它需要一個新的密鑰(不同的電子郵件和ID)。但是,它確實與前兩行共享一封電子郵件,這意味着所有三個應該被分組爲具有相同新密鑰的單個客戶。 – EvanMPW

回答

1

OLDTABLE - 是你的表 newtable的 - WIL l具備導致

enter image description here

CREATE TABLE #NEWTABLE 
(
    NEW_CUST_KEY int not null , 
    CUST_ID int not null, 
    CUST_EMAIL nvarchar(100) null 
) 
------------------------------------ 
insert into #NEWTABLE (NEW_CUST_KEY,CUST_ID,CUST_EMAIL) 
SELECT ROW_NUMBER() OVER(ORDER BY CUST_ID, CUST_EMAIL) AS NEW_CUST_KEY, CUST_ID, CUST_EMAIL 
FROM 
(
    SELECT CUST_ID, CUST_EMAIL 
    FROM OLDTABLE 
    GROUP BY CUST_ID, CUST_EMAIL 
) T 


UPDATE Upd SET NEW_CUST_KEY = T.NEW_CUST_KEY 
FROM #NEWTABLE Upd 
join (
    SELECT CUST_ID, min(NEW_CUST_KEY) AS NEW_CUST_KEY 
    FROM #NEWTABLE 
    GROUP BY CUST_ID) T 
on Upd.CUST_ID = T.CUST_ID 

UPDATE Upd SET NEW_CUST_KEY = T.NEW_CUST_KEY 
FROM #NEWTABLE Upd 
join (
    SELECT CUST_EMAIL, min(NEW_CUST_KEY) AS NEW_CUST_KEY 
    FROM #NEWTABLE 
    GROUP BY CUST_EMAIL) T  
on nullif(Upd.CUST_EMAIL,'') = nullif(T.CUST_EMAIL,'')  

UPDATE Upd SET NEW_CUST_KEY = T.CHANGE_CUST_KEY 
FROM #NEWTABLE Upd 
join (
    SELECT NEW_CUST_KEY, ROW_NUMBER() OVER(ORDER BY NEW_CUST_KEY) AS CHANGE_CUST_KEY 
    FROM #NEWTABLE 
    GROUP BY NEW_CUST_KEY) T 
on Upd.NEW_CUST_KEY = T.NEW_CUST_KEY 

select * from #NEWTABLE 
+1

我忘記了空電子郵件。收集一行: on nullif(Upd.CUST_EMAIL,'')= nullif(T。CUST_EMAIL,'') –

+0

更新:在答案更改圖片 –

0

我想你可以使用ROW_NUMBER ..... 這樣的事情。 .....

SELECT DISTINCT CUST_ID, CUST_EMAIL 
ROW_NUMBER() OVER(PARTITION BY CUST_ID, CUST_EMAIL) AS New_Cust_Key 
FROM YOUR TABLES 
+0

ROW_NUMBER這裏只會爲每一行輸出1,因爲您正在通過CUST_ID和CUST_EMAIL進行分區,並且這已經是一個不同的列表。 – EvanMPW

0

我是想你的用戶與他們的ID,以他們的電子郵件,反之亦然,當我創造了這個弗蘭肯斯坦怪物查詢結果地圖:

DECLARE @Customers TABLE 
(
    CUST_ID INT 
    , CUST_EMAIL VARCHAR(20) 
); 

INSERT INTO @Customers (CUST_ID, CUST_EMAIL) 
VALUES (123, '[email protected]') 
    , (123, '[email protected]') 
    , (124, '[email protected]') 
    , (125, '[email protected]') 
    , (126, '') 
    , (127, '') 
    , (128, '[email protected]') 
    , (128, '[email protected]') 
    , (129, '[email protected]'); 


SELECT DISTINCT C.CUST_ID 
    , C.CUST_EMAIL 
    , DENSE_RANK() OVER(ORDER BY T.CUST_ID) AS NEW_CUST_KEY 
FROM @Customers AS C 
INNER JOIN (
    SELECT CUST_ID, CUST_EMAIL 
    FROM @Customers 
    EXCEPT 
    SELECT C2.CUST_ID, C2.CUST_EMAIL 
    FROM @Customers AS C1 
    INNER JOIN @Customers AS C2 
    ON C2.CUST_EMAIL = C1.CUST_EMAIL 
    AND C2.CUST_ID > C1.CUST_ID 
    AND C1.CUST_EMAIL <> '' 
) AS T 
    ON CASE 
    WHEN (T.CUST_ID = C.CUST_ID AND T.CUST_EMAIL = C.CUST_EMAIL AND T.CUST_EMAIL = '') THEN 1 
    WHEN (T.CUST_ID = C.CUST_ID OR T.CUST_EMAIL = C.CUST_EMAIL) AND T.CUST_EMAIL <> '' THEN 1 
    ELSE 0 
    END = 1; 

使用你的測試數據,它產生了這個,它確實看起來符合你的期望:

╔═════════╦═════════════════╦═══════════════╗ 
║ CUST_ID ║ CUST_EMAIL ║ NEW_CUST_KEY ║ 
╠═════════╬═════════════════╬═══════════════╣ 
║  123 ║ [email protected] ║    1 ║ 
║  123 ║ [email protected] ║    1 ║ 
║  124 ║ [email protected] ║    2 ║ 
║  125 ║ [email protected] ║    2 ║ 
║  126 ║     ║    3 ║ 
║  127 ║     ║    4 ║ 
║  128 ║ [email protected] ║    5 ║ 
║  128 ║ [email protected] ║    5 ║ 
║  129 ║ [email protected] ║    5 ║ 
╚═════════╩═════════════════╩═══════════════╝ 

你可以在現實生活中看到這個data.stackexchange.com

讓我知道這是否適用於您的實際數據庫。

+1

我在這裏newby。感謝您訪問data.stackexchange.com。非常有用的資源。 @Evaldas –

+0

@evaldas有沒有辦法解決這個問題,如果用戶,如果列cust_id被替換爲手機號碼? –