2013-07-26 54 views
0

我有一個表TPAIE,2條信息:刪除所有,但一個行基於幾個標識符

  • numben(數受益人)
  • datPai(年月日時我付出的傢伙)

通常對於一個約會,我必須有一個受益人(我支付一次約會的人)。儘管如此,它發生,我有幾行相同的受益者,同日

COUNTING NUMBEN PERPAI 

    9 75005100 01/08/13 
    9 75005109 01/08/13 

我怎麼能刪除所有的行,但一個爲這些beneficiairy和具體日期?

注:我發現類似的東西,但它的作品,如果我只有一個標識符

delete from tpaie where numben not in 
(select min(numben) from tpaie group by numben, perpai); 

注2:我發現這個SQL可能刪除存在幾次都行:我只是說'不要刪除第一個)。一個rownum的地方?

delete from tpaie a 
where (numben, perpai) in (
select numben, perpai from tpaie b where b.rowid <> a.rowid)  
+0

「刪除所有的行,但一個」。你不想刪除哪一個? –

+1

在你的例子中'COUNTING'是相同的,但NUMBEN'不同,是故意的嗎? –

+0

@Dour High:任何人,他們是一樣的 – mlwacosmos

回答

2

有了您的第二次嘗試你是NEA從目標r。您只需要瞭解rowid是唯一物理錶行標識符的保留字。查詢documentation瞭解更多信息。

查詢:

delete tpaie 
where rowid not in (
    select distinct 
    (first_value(rowid) over (
     partition by numben, perpai order by rowid 
    ) 
    ) first_row_id 
    from 
    tpaie 
) 

你可以看到完整的測試中this SQLFiddle

更新
@mlwacosmos發現了一個性能更好的變體。當然,原始答案中的not in並不是一個好的做法。於是我加了他的變體來回答過於供將來參考:

delete from tpaie a 
where 
    rowid not in ( 
    select distinct 
     (first_value(rowid) 
      over (partition by numben, perpai order by rowid) 
    ) first_row_id 
    from 
     tpaie b 
    where 
     a.numben = b.numben 
     and 
     a.perpai = b.perpai 
) 
    and 
    (numben, perpai) in (select numben, perpai 
         from tpaie b 
         where b.rowid <> a.rowid 
        ) 

SQLFiddle

但這個解決方案又包括not in,這樣可以更好地使用in功能與其他分析排名:

delete from tpaie a 
where 
    rowid in ( 
    select row_id 
    from (
     select 
     rowid row_id, 
     (dense_rank() over (-- enumerate rows 
      partition by numben, perpai order by rowid 
     ) 
     ) row_rank 
     from 
     tpaie 
    ) 
    where 
     row_rank > 1 -- eliminate rows ranked first 
) 

SQLFiddle

+0

+1,Great!,對於SQLFiddle中的查詢和示例,我不知道:FOR VAR IN 1 x LOOP,ROWID,ROWIDTOCHAR和first_value。謝謝。 –

+0

對不起,我無法將此答案設置爲已接受,因爲我沒有提出問題。你的答案也有助於我解決其他問題。 –

+0

@GastonF。對不起,我只是誤了你和原來的海報。我希望你能原諒我這個錯誤。但順便說一句,我幾乎在與你同時學習'ROWIDTOCHAR',因爲從來沒有像[SQLFiddle](http://www.sqlfiddle.com/#!4/dc56e/12)處理JDBC輸出。我之前使用的所有客戶端應用程序只是將'rowid'值作爲字符串輸出。所以,在回答問題時也可以學習。 :) – ThinkJet

0

在主表中創建DISTINCT一個temporay表,讓每日期每本只有一個入口,delele所有條目,並與臨時表重新加載它,像:

SELECT DISTINCT numben, perpai 
INTO #temp 
FROM tpaie 

DELETE FROM tpaie 

INSERT INTO tpaie 
SELECT * FROM #temp 

編輯:

對於一個特定的日期,請嘗試:

SELECT DISTINCT numben, perpai 
INTO #temp 
FROM tpaie 
WHERE perpai = '01/08/13' 

DELETE FROM tpaie 
WHERE perpai = '01/08/13' 

INSERT INTO tpaie 
SELECT * FROM #temp