2017-07-26 17 views
0

之一查找並更新非重複記錄我想找到所有非重複記錄並更新其中一列。根據列

Ex。

Col_1 | Col_2 | Col_3 | Col_4 | Col_5 
A  | AA | BB | 1  | 
A  | AB | BC | 2  | 
A  | AC | BD | 3  | 
B  | BB | CC | 1  | 
B  | BB | CC | 2  | 
C  | CC | DD | 1  | 

我的查詢必須按Col_1進行分組,我想根據Col_2和Col3找出沒有唯一的記錄,然後更新Col_5。

基本上輸出應該如下,

Col_1 | Col_2 | Col_3 | Col_4 | Col_5 
A  | AA | BB | 1  | 1 
A  | AB | BC | 2  | 1 
A  | AC | BD | 3  | 1 
B  | BB | CC | 1  | 0 
B  | BB | CC | 2  | 0 
C  | CC | DD | 1  | 0 

有沒有人有一個想法,我怎麼能做到這一點?這是一個龐大的數據庫,因此性能也是一個關鍵因素。

感謝堆,

+0

可否請您提供您嘗試過的任何查詢? – Fmanin

+0

對不起,我仍然無法寫出任何我想要的東西。謝謝 – Ash

+0

爲什麼最後一行沒有更新? – gotqn

回答

0

有很多方法可以做到這一點。這個解決方案來自我可以訪問的postgres,但我敢打賭,它也將在tsql上工作,因爲應該有通用的語法。

;WITH 
cte_1 AS (
    SELECT col_1 FROM some_table GROUP BY col_1 HAVING count(*) > 1 
), 
cte_2 AS (
    SELECT col_1 FROM some_table GROUP BY col_1, col_2, col_3 HAVING count(*) > 1 
), 
cte_3 AS (
    SELECT cte_1.col_1 FROM cte_1 
    LEFT JOIN cte_2 ON cte_1.col_1 = cte_2.col_1 
    WHERE cte_2.col_1 IS NULL 
) 
UPDATE some_table SET col_5 = 1 
FROM cte_3 WHERE cte_3.col_1 = some_table.col_1; 

那麼,上面會發生什麼?

  1. 首先,我們建造3 CTE半表,其允許我們邏輯分割成較小的部分:

    • cte_1,其提取其中可以有多個col2col_3
    • cte_2行,其選擇那些其中有非唯一的col_2col_3
    • cte_3它返回那些col_1這只是LEFT JOIN
  2. 使用最後cte_3結構,我們能夠有獨特的col_2col_3更新some_table正確

我假設你的表稱爲some_table這裏。如果您對性能感到擔憂,那麼您應該在這裏提供一些主鍵,並且在col_2col_3(單獨使用,但如果這些將在(col_1, col_2)等等上合成)可能會有所幫助。

你也可能需要將其從移動CTE使用臨時表(可以同時索引以提高效率。

也請注意,此查詢正常工作與你的榜樣,但沒有真實數據很可能只是猜測。我的意思是會發生什麼,當你將有col_1 =在同一時刻把一些獨特的和非潮頭col_2

,但我相信這是好點開始。

+0

感謝您的詳細解答,正如您所說,col_1有一些獨特和非獨特的功能時不起作用。所以我更新了CTE如下。 – Ash

0
;WITH 
cte_1 AS (
    SELECT col_1, count(*) as items FROM some_table GROUP BY col_1 HAVING count(*) > 1 
), 
cte_2 AS (
    SELECT col_1, count(*) as items FROM some_table GROUP BY col_1, col_2, col_3 HAVING count(*) > 1 
), 
cte_3 AS (
    SELECT cte_1.col_1 FROM cte_1 
    LEFT JOIN cte_2 ON cte_1.col_1 = cte_2.col_1 
    WHERE cte_2.col_1 IS NULL OR cte_1.items > cte_2.items 
    GROUP BY cte_1.col_1 
) 
UPDATE some_table SET col_5 = 1 
FROM cte_3 WHERE cte_3.col_1 = some_table.col_1;