プロが教える店舗&オフィスのセキュリティ対策術

お世話になります。
最近データベースを触り始めた初心者です。
色々見たのですが、分からなかった為、教えて下さい。

   テーブル名: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)を残したいという事です。)

どのようにして条件を指定すれば良いのかが分かりません。
どなたか、よろしくお願い致します。

A 回答 (5件)

考え方としては、顧客名と郵便番号でグルーピングし、その中での最大の受注日付を取得します。

その結果と、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の精度は保証できませんが試してみてください。

この回答への補足

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

補足日時:2004/01/06 11:39
    • good
    • 0
この回答へのお礼

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

お礼日時:2004/01/07 19:06

条件をまとめると、



・ 顧客名と郵便番号が重複しているレコードだけを
  削除したい。

・ 削除後に重複しているレコードのうち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を実際に実行してみたわけではないので、
精度・パフォーマンス等は保障できませんが。
    • good
    • 0
この回答へのお礼

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

お礼日時:2004/01/07 19:07

横槍失礼します。

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

で削除対象データが全て取得できると思いますが。

この回答への補足

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

補足日時:2004/01/06 13:19
    • good
    • 0
この回答へのお礼

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

お礼日時:2004/01/07 19:06

データを抽出することが目的(画面表示やレポート出力のため)なら #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)のどちらか(どちらでもよい?)を削除するのなら、ちょっと面倒な記述になるような気がします。(まだちゃんと考えてないのですが。)

この回答への補足

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

補足日時:2004/01/06 11:29
    • good
    • 0
この回答へのお礼

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

お礼日時:2004/01/07 19:05

SELECT 顧客名,郵便番号c,MAX(受注日付)


FROM table1
GROUP BY 顧客名,郵便番号;

で取れませんか?さらに項目が多い場合は工夫が必要ですが。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!