2015-04-07 19 views
1

我在嘗試,如果我的客戶表包含以下從我的表,例如刪除重複行:在多個查詢中使用「with」語句?

first_name last_name email 
fred   wilford  [email protected] 
fred   wilford  [email protected] 
Damian  Jones  [email protected] 

理想的結果應該是以下幾點:

first_name last_name email 
fred   wilford  [email protected] 
Damian  Jones  [email protected] 

這應該是相當簡單在刪除主表中的重複項之前,使用包含重複行的中間表執行操作,並最後將中間表中的所有行插入主表中。不過,我寧願刪除中間表,只是使用類似的語句。 考慮下面的例子:

with dups as 
(
    select name,last_name,email from customer group by 1,2,3 having 
    count(*) > 1 
) 
delete from customer 
using 
(
    select name,last_name,email from customer group by 1,2,3 having  
    count(*) > 1 
)b 
where b.name = customer.name; 
insert into customer 
(
    select name,last_name,email from dups 
) 

麻煩的是最終的INSERT語句未能按「DUP的」不被認可。有沒有辦法來解決這個問題?在此先感謝

+0

通用表防爆壓力只存在於主查詢中 - 您需要使用臨時表或表變量在多個查詢中使用它。 –

回答

2

你也可以做這樣:

模式:

create table tbl (first_name varchar(50), 
        last_name varchar(50),  
        email varchar(50)); 
insert into tbl values 
('fred','wilford','[email protected]'), 
('fred','wilford','[email protected]'), 
('Damian','Jones','[email protected]'); 

執行此操作:

CREATE TABLE temp (first_name varchar(50), 
        last_name varchar(50),  
        email varchar(50)); 
INSERT INTO temp SELECT DISTINCT * FROM tbl; 
DROP TABLE tbl; 
ALTER TABLE temp RENAME TO tbl; 

檢查:

select * from tbl; 

結果:

first_name last_name email 
fred  wilford  [email protected] 
Damian  Jones  [email protected] 
+0

不錯,這種方式更清潔! – godzilla

+1

僅供將來參考,有幾件事情可能會使這種方法變得更加複雜。你需要重新創建索引,外鍵等。 –

+0

@DStanley你是對的,100%同意,另加1你的有用評論。 – jfun

0

取而代之的是WITH條款,你可以創建dups作爲一個臨時表:

CREATE TEMP TABLE dups (name, last_name, email) AS 
(
    select name,last_name,email from customer group by 1,2,3 having 
    count(*) > 1 
); 
+0

是這就是我已經,好吧,因爲我不能用於多個查詢語句,這將不得不做 – godzilla

+0

@godzilla:你可以使用一個CTE(「with語句」)多個查詢。請參閱Jakub的回答 –

+0

哪個線程,可以請你提供一個鏈接?謝謝! – godzilla

3

您可以chain the CTE,如果你想:

WITH dups AS 
(
    select name,last_name,email from customer group by 1,2,3 having 
    count(*) > 1 
), 
del AS(
    DELETE FROM customer USING dups WHERE dups.name = customer.name RETURNING dups.* 
), 
ins AS(
    INSERT INTO customer(name,last_name,email) SELECT name,last_name,email FROM del RETURNING del.* 
) 
SELECT * FROM ins; 
+0

您可以在CTE中執行DELETE或INSERT嗎? –

+0

@DStanley是的,你可以。 –