2017-10-09 85 views
0

我有如下表:SQL:如何刪除基於一個條件,從表中的行

tbl 
source type date 
---  ---  --- 
google A  2010-02-25 
google A  2013-04-11 
facebook C  2008-10-22 
facebook C  2007-01-28 

我想只保留每個源的一個條目,而標準是選擇具有min(date) group by source源元組。該表由數百萬條記錄組成,我正在尋找刪除多餘記錄的有效方法。 - 離手 - 這是我能想到的,使這個更有效的是將聚集結果存儲在一個子查詢

delete t 
    from t join 
     (select source, min(date) as mindate 
      from t 
      group by source 
     ) tt 
     on t.source = tt.source 
    where t.date > tt.mindate; 

的唯一方法:

+0

該表是否有任何唯一的標識符(即主鍵,ID字段等)? –

+0

@ChrisJ nah,它沒有。 – SaadH

回答

2

在MySQL中,你可以使用join做到這一點併爲其添加索引。

我還可以補充說,無論用於確定要刪除的行的計算如何,都會以低效率刪除表中的大量行。通常,我會推薦三步法:

  1. 編寫查詢以生成所需的表並將結果存儲在臨時表中。
  2. 截斷原始表格。
  3. 重新插入(很多)較少的行數。
0

在Microsoft SQL中,您可以試試這個。

; 
WITH cte 
     AS (SELECT ROW_NUMBER() OVER (PARTITION BY source, type 
             ORDER BY createdate) RN 
      FROM tbsource) 
DELETE FROM cte 
WHERE RN > 1; 
+0

這不是MySQL語法。 。 。在這麼多方面。 –

+0

@戈登林諾夫,對不起。這個問題並不包含MySQL。 – Madhukar

+0

有一個mysql標籤,但如果應該是這樣的話,可能也應該在標題中。 – mikato

0
delete from t where date not in (select al.d from (select min(date) as d from t group by source)al); 
+0

謝謝你的這段代碼,它可能會提供一些有限的即時幫助。通過展示*爲什麼*這是一個很好的解決方案,並且使它對未來的讀者更有用,一個正確的解釋[將大大提高](// meta.stackexchange.com/q/114762)其長期價值其他類似的問題。請[編輯]你的答案以添加一些解釋,包括你所做的假設。 –

0

到重複表添加標識列充當行唯一標識符(自動增量升序)序列號:

alter table tbl add sno int identity(1,1) 

table

這個查詢只選擇非重複行最小(日期):

(select min(date),sno From tbl group by source) 

所以「sno」將等於「1」和「4」。

現在有了這個表連接,並刪除加入該的記錄是重複的(t.sno爲null)從這個鏈接的方法3調整

delete E from tbl E 
    left join 
    (select min(date),sno From tbl group by source) T on E.sno=T.sno 
where T.sno is null 

table3

解決方法:LINK

相關問題