• ベストアンサー

Oracle  重複データの削除の仕方について教えて下さい

お世話になります。 最近データベースを触り始めた初心者です。 色々見たのですが、分からなかった為、教えて下さい。    テーブル名:table1   顧客名    郵便番号  受注日付   customer_nm  post_no  jutyu_ymd  -------------------------------------------- (1) 鈴木一郎    1111111  2004/01/05    (2) 鈴木一郎    1111111  2003/07/01     (3) 佐藤花子    2222222 2002/09/30 (4) 佐藤花子    2222222  NULL  上記のような、顧客テーブルがあったとします。 顧客名と郵便番号が同一だけれど、日付が違う為、重複 データとなってしまっています。 日付の古い方を削除、またNULLの場合は日付のある方を 残したいと考えています。 (つまり、上の場合は(1)と(3)を残したいという事です。) どのようにして条件を指定すれば良いのかが分かりません。 どなたか、よろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

考え方としては、顧客名と郵便番号でグルーピングし、その中での最大の受注日付を取得します。その結果と、table1の受注日付を比較し、一致しなければ削除をすれば可能な気がします。 SELECT T1.* FROM TABLE1 T1,(SELECT CUSTOMER_NM,POST_NO,MAX(JUTYU_YMD) JUTYU_YMD FROM TABLE1 GROUP BY CUSTOMER_NM,POST_NO) T2 WHERE T1.CUSTOMER_NM = T2.CUSTOMER_NM AND T1.POST_NO = T2.POST_NO AND T1.JUTYU_YMD != T2.JUTYU_YMD これで、削除したいデータが検索できませんか?即席でSQLの精度は保証できませんが試してみてください。

eflows
質問者

お礼

なんとか無事処理することが出来ました。 ご協力いただいた皆様、お時間割いていただきありがとうございました。素人なもので、一人では前に進めなかった為、本当に感謝です。

eflows
質問者

補足

なるほど。この様に書けば、古い日付分が抽出できるのですね。自分では見当がつけられなかったので、とても助かります。 ただ、当方のデータベースの場合、きれいに全て日付が入っている状態ではありません。NO.2の方のところに書いた通りの状況です。 上記のSQLで古いデータを削除してから、日付重複分と、日付NULL分はdistinctを使って重複を取り除くのが良いでしょうか?

その他の回答 (4)

  • takopon
  • ベストアンサー率69% (27/39)
回答No.5

条件をまとめると、 ・ 顧客名と郵便番号が重複しているレコードだけを   削除したい。 ・ 削除後に重複しているレコードのうち1レコードだけ   は必ず残したい。 ・ 残す優先度は、   (1) 日付が最新   (2) 日付がNULLでない という感じてよいのであれば、安直ですが、 まず、 DELETE TABLE1 WHERE (select count(*) from TABLE1 SUB1 where SUB1.顧客名 = TABLE1.顧客名 and SUB1.郵便番号 = TABLE1.郵便番号 ) > 1 AND ( ( TABLE1.受注日付 <> (select MAX(SUB2.受注日付) from TABLE1 SUB2 where SUB2.顧客名 = TABLE1.顧客名 and SUB2.郵便番号 = TABLE1.郵便番号 ) OR ( TABLE1.受注日付 is null ) ) AND (select MAX(SUB3.受注日付) from TABLE1 SUB3 where SUB3.顧客名 = TABLE1.顧客名 and SUB3.郵便番号 = TABLE1.郵便番号 ) is not null を実行します。 これで、顧客名・郵便番号が重複し、 すべてのレコードの受注日付が、同じまたはNULLでない データが消せると思います。 その後さらに、 DELETE TABLE1 WHERE (select count(*) from TABLE1 SUB1 where SUB1.顧客名 = TABLE1.顧客名 and SUB1.郵便番号 = TABLE1.郵便番号 ) > 1 AND ( TABLE1.ROWID <> (select MAX(SUB2.ROWID) from TABLE1 SUB2 where SUB2.顧客名 = TABLE1.顧客名 and SUB2.郵便番号 = TABLE1.郵便番号 ) ) で、残る顧客名・郵便番号・受注日付すべてが重複しているデータを一つだけ残して削除できると思います。 このSQLを実際に実行してみたわけではないので、 精度・パフォーマンス等は保障できませんが。

eflows
質問者

お礼

なんとか無事処理することが出来ました。 ご協力いただいた皆様、お時間割いていただきありがとうございました。素人なもので、一人では前に進めなかった為、本当に感謝です。

  • PAPA0427
  • ベストアンサー率22% (559/2488)
回答No.4

横槍失礼します。#1の者です。 #3さんのmomo rightさんのSQLをモデファイすれば出来ますよ。 SELECT T1.* FROM TABLE1 T1,(SELECT CUSTOMER_NM,POST_NO,MAX(JUTYU_YMD) JUTYU_YMD FROM TABLE1 GROUP BY CUSTOMER_NM,POST_NO) T2 WHERE T1.CUSTOMER_NM = T2.CUSTOMER_NM AND T1.POST_NO = T2.POST_NO AND (T1.JUTYU_YMD != T2.JUTYU_YMD OR T2.JUTYU_YMD IS NULL) で削除対象データが全て取得できると思いますが。

eflows
質問者

お礼

なんとか無事処理することが出来ました。 ご協力いただいた皆様、お時間割いていただきありがとうございました。素人なもので、一人では前に進めなかった為、本当に感謝です。

eflows
質問者

補足

すみません。ご協力いただいて、大変助かります。 私も上記のように考えてはみたのですが、重複していないデータの中にも受注日がNULLのものが存在する為、OR条件で受注日がNULLのデータも抽出すると、重複していないデータまでもひろってしまうのです。 記述不足ですみませんでした。

回答No.2

データを抽出することが目的(画面表示やレポート出力のため)なら #1 さんの回答が全てだと思うのですが、もしかすると目的は不要データの削除(ディスク・スペースを空けるためや、パフォーマンス改善のためなど?)なのでしょうか? 削除することが目的だとすると、一つお聞きしたいのですが、 顧客名+郵便番号+受注日付の組み合わせは一意になっているのでしょうか?つまり (1) 鈴木一郎    1111111 2004/01/05 (2) 鈴木一郎    1111111 2004/01/05 (3) 鈴木一郎    1111111 2003/07/01 (4) 佐藤花子    2222222 2002/09/30 (5) 佐藤花子    2222222 NULL の(1)、(2)ようなデータはあり得ないのでしょうか? もし、顧客名+郵便番号+受注日付の組み合わせは一意になっていなくて、(1)、(2)のどちらか(どちらでもよい?)を削除するのなら、ちょっと面倒な記述になるような気がします。(まだちゃんと考えてないのですが。)

eflows
質問者

お礼

なんとか無事処理することが出来ました。 ご協力いただいた皆様、お時間割いていただきありがとうございました。素人なもので、一人では前に進めなかった為、本当に感謝です。

eflows
質問者

補足

あぁ、全くその通りなのです。 説明不足で申し訳ありません。 顧客名+郵便番号+受注日付すべて重複しているデータもあるのです。その場合は削除はどちらでも構いません。 上記のような例もあり、NULLもあり、(重複データで、どちらも日付がNULLというパターンもあります)というごちゃごちゃしたデータベースになってしまっています。 残したいデータ以外には削除フラグを立てたいと考えています。

  • PAPA0427
  • ベストアンサー率22% (559/2488)
回答No.1

SELECT 顧客名,郵便番号c,MAX(受注日付) FROM table1 GROUP BY 顧客名,郵便番号; で取れませんか?さらに項目が多い場合は工夫が必要ですが。

関連するQ&A

  • Accessで一致データを抜いて項目をずらす方法

    Access2000を使用して、テーブル1のフィールド2~5で、テーブル2と一致したフィールドを抜いて項目をシフトさせたいのですが、どのような方法があるのでしょうか。 <元テーブル>    フィールド→ 氏名, 名1, 名2, 名3, 名4 ・テーブル1の項目 山田,花子,次郎,三郎,四郎           鈴木,五郎,六郎,七朗,和子           佐藤,和子,一郎,太郎,四郎 ・テーブル2の項目 山田,花子           鈴木,七朗           鈴木,和子          佐藤,一郎           佐藤,四郎           佐藤,和子 <変換後テーブル>テーブル1を基準として   フィールド→ 氏名, 名1, 名2, 名3, 名4           山田,次郎,三郎,四郎,null           鈴木,五郎,六郎,null,null           佐藤,太郎,null,null,null 分りずらい説明で申し訳ありませんが、宜しくお願いします。

  • オラクルのビューについて

    (顧客テーブル) 項目名 顧客コード、顧客名、顧客名カナ (商品テーブル) 項目名 商品コード、商品名、受注単価 (受注テーブル) 項目名 受注番号、顧客コード、受注年月日、納入予定年月日 (受注明細テーブル) 項目名 受注番号、商品コード、受注数量 を使って次のビューを作ります。 (商品別受注日計データ) 項目名  商品コード 商品名 受注単価 受注年月日 日計商品別受注数量  受注数量(受注明細テーブル)の合計 日計商品別受注金額  受注単価*日計商品別受注数量 このときに日計商品別受注金額を求めるには先に日計商品別受注数量を求めておかなければなりませんが、これを一つのSELECT文で行う事は可能でしょうか。 そのまま一つのSELECT文でやろうとするとGROUP BYでうまくいかないのですが、 やはり先に日計商品別受注数量を求めておかなければいけないのですか? どっちにしろやり方がわかりません。

  • エクセル キーとなる項目で判別し重複データ行を削除したい

    エクセル2002を使用しています。 差込印刷用のデータとして整える方法を教えていただきたいと存じます。 具体的には、子供ごとのレコードデータから、親宛の封筒宛名ラベルを作成したいと考えていて、2人兄弟や3人兄弟の場合でも封筒は1通なので、 キーとなる項目を目安に、不必要な行を削除すればできると考えましたが、具体的な方法がわからないでいます。 現在のデータは、以下のものです。(簡潔にするために列を部分的に省いています) 世帯コード   親の氏名   住所           子の氏名 0011223    鈴木 一郎  東京都千代田区一丁目   鈴木 次郎 0011223    鈴木 一郎  東京都千代田区一丁目   鈴木 三郎 0011223    鈴木 一郎  東京都千代田区一丁目   鈴木 四郎 0011556    山田 花子  埼玉県川口市中央     山田 洋子 0011556    山田 花子  埼玉県川口市中央     山田 和夫 0153355    佐藤 次郎  千葉県船橋市海浜     佐藤 みく 0002333    鈴木 一郎  神奈川県川崎区高津区   鈴木 空 0002333    鈴木 一郎  神奈川県川崎区高津区   鈴木 陸 これを、次のように「世帯コード」で判別して世帯ごとの最初の行だけを抜き出したり、2行目以降を削除したりできれば、差込印刷用のデータとして利用できると思います。 世帯コード   親の氏名   住所           子の氏名 0011223    鈴木 一郎  東京都千代田区一丁目   鈴木 次郎 0011556    山田 花子  埼玉県川口市中央     山田 洋子 0153355    佐藤 次郎  千葉県船橋市海浜     佐藤 みく 0002333    鈴木 一郎  神奈川県川崎区高津区   鈴木 空 (世帯ごとに一行ずつになっています。親の氏名のうち、鈴木 一郎 さんは、同姓同名の方です。世帯コードが違うので区分できます。) エクセルの機能でこのようにできる方法はあるでしょうか? もしくは別の方法でも、宛名ラベルを親宛に一枚印刷できる方法があるでしょうか? お願いいたします。 データ用のシートですので、行や列の挿入や別シートの利用などはすべてできますので、よろしくお願いいたします。

  • SQL:重複を削除した場合の別テーブルの更新

    下記のようなことを行いたいのですが、もう数十時間悩んでおり、このままだとクビになります。 以下のようなテーブルが2つあります ■テーブルA 顧客ID なまえ 内線 ―――――――― 001、 佐藤、 001 ※同じ(これだけ残す) 002、 鈴木、 002 003、 田中、 003  004、 佐藤、 001 ※同じ(削除) 005、 佐藤、 004 006、 鈴木、 005 007、 佐藤、 001 ※同じ(削除) ■テーブルB 伝票ID 顧客ID 購入物 001、 001、 ガム ※対応する顧客は残る 002、 003、 チョコレート 003、 004、 塩  ※対応する顧客が残らない 004、 006、 ガム 005、 002、 塩 006、 007、 塩  ※対応する顧客が残らない テーブルAの佐藤4人中3人は、名前も内線も同じなので 顧客IDは一番小さいものだけ残し、あとは同一とみなし重複行を削除します。 そうするとテーブルBの伝票IDの001、003、006の顧客IDは全部が佐藤だったのですが 重複を削除してしまったため、003と006に対応する顧客がテーブルAから消えてしまいます。 なので、テーブルAの重複を削除するときに、同時にテーブルBの顧客IDも 一緒に一番小さい顧客IDに更新したいのです。 どうか宜しくお願いいたします。

  • クエリを結合したいのですが…。

    クエリを結合したいのですが…。 クエリ1、クエリ2、があったとして、 クエリ1には 代表者名、家族名a、 佐藤太郎、佐藤花子 鈴木四郎、鈴木桜 クエリ2には 代表者名、家族名b、 田中一郎、田中菊 とあったとします。 新しくクエリを作成し、 代表者名、家族名 佐藤太郎、佐藤花子 鈴木四郎、鈴木桜 田中一郎、田中菊 と、クエリ1とクエリ2を合わせたものを作りたいのですが、実際可能でしょうか?アクセス2003を使用しています。ご教授宜しくお願い致します。

  • アクセスのクエリで重複しているデータについて

    テーブルの一部分のフィールドを使ってクエリAを作成しています。 [クエリA] 番号 氏名  郵便番号 住所     電話番号 子供 1  田中守  111-0000 東京都・・・ 000-0000 章 2  佐藤健  122-0001 神奈川県・・・ 001-0001 花子 3  田中守  111-0000 東京都・・・ 000-0000 陽子 これを重複しているデータを省くのですが、[子供]の名前はすべて取り出したいと思っています。 どの様にすれば良いか教えて頂けないでしょうか? 氏名  郵便番号 住所     電話番号 子供 田中守  111-0000 東京都・・・ 000-0000 章,陽子 佐藤健  122-0001 神奈川県・・・ 001-0001 花子 最終的には、宛名印刷を行った時に、子供の名前も連名で表示したいと思っての事です。 現在、クエリで行っておりますが、クエリでなくても構いません。 足りない情報はすぐに補足致しますので、お手数ですが、どうぞよろしくお願い致します。 Access2003を使用しております。

  • Accessの文字の置換のクエリについて

    Accessについて教えて下さい。 SQLデータベースをODBCを使用して、Accessにてリンクしています。 テーブルのあるフィールドに顧客名が並んでいます。 頭の一文字を○に置換するには、どのようなクエリを組めばいいのでしょうか? 山田 太郎⇒○田 太郎 田中 一郎⇒○中 一郎 佐藤 花子⇒○藤 花子 また、間にスペースが入っている後の文字(名)の置換の方法も教えて下さい。

  • Accessでの文字の置換のクエリについて

    Accessについて教えて下さい。 SQLデータベースをODBCを使用して、Accessにてリンクしています。 テーブルのあるフィールドに顧客名が並んでいます。 頭の一文字を○に置換するには、どのようなクエリを組めばいいのでしょうか? 山田 太郎⇒○田 太郎 田中 一郎⇒○中 一郎 佐藤 花子⇒○藤 花子 また、間にスペースが入っている後の文字(名)の置換の方法も教えて下さい。

  • Accsessでの重複データの処理に関して

    Accessを使用している者ですが、どうにも判らない事だらけですので、 どなたかご教授ください。 現在、顧客情報の入っているTableがあります。 項目は、 ・顧客名 ・電話番号 ・住所 ・注文日 です。 この中には、同一人物が重複して登録されています。 この重複しているもの 例)電話番号と顧客名が同一   顧客名と住所が同一 等 をまとめたいと思っておりますが、その際に 重複しているデータの注文日の新しい日付のデータを保持したいと思います。 例) 顧客名 A  電話番号 0120-11-1111  注文日 2009/01/01   顧客名 A  電話番号 0120-11-1111  注文日 2009/05/01であれば、    顧客名 A  電話番号 0120-11-1111  注文日 2009/05/01 こちらにまとめる。   どなたかご教授ください。 宜しくお願い致します。

  • 23歳の事務をやっているOLです。エクセルでの重複データ抽出についての

    23歳の事務をやっているOLです。エクセルでの重複データ抽出についての質問です。仕事で2つのデータから重複データを抽出しないといけなくなったのですが、エクセルはよくわからないので質問させてください。データには顧客番号と名前が入っています。   A列    B列 1 顧客番号  名前 2 1234   田中太郎 3 2345   鈴木一郎 4 3456   佐藤次郎 5 4567   伊藤三郎 6 5678   吉田四郎 ・ ・ ・ データの形式は2つともこのような感じです。 データAには約1,000件のデータがあり、データBには約300件ほどのデータがあります。 AとBの顧客番号が重複している人の顧客番号と名前を上と同じような感じで別のファイルに表示させたいのですが、どうやってやったらいいのかわかりません>< 助けてください。 どうかよろしくお願いします。