0

私は1つのテーブルTPAIE、2つの情報を持っています:

  • numben(受益者の番号)
  • datPai (私が男に支払う日付)

通常、1 回のデートで 1 人の受益者が必要です (1 回のデートで 1 回支払います)。それでも、たまたま同じ受取人で同じ日付の回線がいくつかあります

    COUNTING NUMBEN   PERPAI 

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

これらの受益者のそれぞれと特定の日付の行を除いて、すべての行を削除するにはどうすればよいですか?

注:そのようなものを見つけましたが、識別子が1つしかない場合は機能します

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)      
4

2 に答える 2

2

2 回目のトライで、ゴールに近づいています。rowid一意の物理テーブル行識別子の予約語であることを理解する必要があります。詳細については、ドキュメントを参照してください。

クエリ:

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

この 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 
                      )

SQLフィドル

しかし、この解決策には再び関係があるため、別の分析ランキングで関数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
  )

SQLフィドル

于 2013-07-26T17:16:15.853 に答える