質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

3回答

1671閲覧

(postgres)以下の条件で削除するDELETE文があれば知りたい

m6159

総合スコア1

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2021/07/09 08:34

編集2021/07/09 10:14

前提・実現したいこと

お世話になります。
SQLを使用して不要なデータを削除を行いたいのですが、条件をどのように指定すれば良いかわかりません。もし

発生している問題・エラーメッセージ

本来、登録の際に商品ID1つに対して発注番号1つの所、セットで登録された商品IDが複数の発注番号に紐付けられており、増えてしまった不正なデータをうまく消したい。

該当のソースコード

商品ID発注番号
gnb76xv9h1cn5uiw23889
nklyqsf30bk2ghxx23889
s6ul0m4wi9jxbim523889
gnb76xv9h1cn5uiw23890
nklyqsf30bk2ghxx23890
s6ul0m4wi9jxbim523890
gnb76xv9h1cn5uiw23891
nklyqsf30bk2ghxx23891
s6ul0m4wi9jxbim523891
7tdpb9uuppg23kkm23959
rpyrgw558ltdubcf23959
7tdpb9uuppg23kkm23962
rpyrgw558ltdubcf23962

以下同様なレコードが数百行

上記のレコードを

商品ID発注番号
gnb76xv9h1cn5uiw23889
nklyqsf30bk2ghxx23890
s6ul0m4wi9jxbim523891
rpyrgw558ltdubcf23959
7tdpb9uuppg23kkm23962

補足情報(FW/ツールのバージョンなど)

PostgreSQL 10.14

###追記
発注番号の重複が無いように、紐付けが増えてしまった物を削除したいです。
下記の部分ですと

商品ID発注番号
gnb76xv9h1cn5uiw23889
nklyqsf30bk2ghxx23889
s6ul0m4wi9jxbim523889
gnb76xv9h1cn5uiw23890
nklyqsf30bk2ghxx23890
s6ul0m4wi9jxbim523890
gnb76xv9h1cn5uiw23891
nklyqsf30bk2ghxx23891
s6ul0m4wi9jxbim523891

正しくは3レコードを登録したかったのですが、
同時に登録した商品IDの数だけ発注番号が重複して登録されております。

商品ID発注番号
gnb76xv9h1cn5uiw23889
nklyqsf30bk2ghxx23890
s6ul0m4wi9jxbim523891

商品IDと発注番号の紐付けについては、以下のパターンでも問題有りません。

商品ID発注番号
nklyqsf30bk2ghxx23889
s6ul0m4wi9jxbim523890
gnb76xv9h1cn5uiw23891
商品ID発注番号
s6ul0m4wi9jxbim523889
gnb76xv9h1cn5uiw23890
nklyqsf30bk2ghxx23891

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/07/09 08:46

残すべきものの条件を明確にしてください。発注番号が一番若いやつを残すのか、それとも。
sazi

2021/07/09 08:52

発注番号からみて数百件のうち残すものがその5件の商品IDという事ですか? 残すものにルールが無いなら、地道に指定した削除を行うしかありませんが。
guest

回答3

0

ブランクがあるので、期待する通りになるかわからない、拙いものでよろしければ。

sql

1delete from t_order 2where order_no in ( 3 select order_no 4 from ( 5 select product_id, order_no 6 from t_order 7 except 8 select product_id, min(order_no) as order_no 9 from t_order 10 group by product_id 11 ) 12);

要は、商品IDと発注番号の組から、商品IDごとの最も若い番号を持つものを除いたものから
発注番号のみ取り出して、
その発注番号を持つものを削除する、って流れのつもり。

投稿2021/07/09 08:57

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m6159

2021/07/09 10:17

回答ありがとうございます、最小値除外によって商品IDの重複を除外する方法参考になります。 発注番号の重複なく商品IDを紐付けたいので、頂いたSQLを参考にして考えてみます。
guest

0

発注番号の重複が無いように、紐付けが増えてしまった物を削除したいです。

テストではなく、本番環境のデータ補正という事ですよね。
こういう不備の場合、手間を考えての自動化をするのではなく、状況をリストアップして、変更するものをチェックし、1件毎に対象を明らかにして、確実に処理する手法を取るべきです。

こういうところで質問をされるレベルなんですから、尚更です。
そもそも、状況が正しく伝えきれてないとしたら、回答も違うものになるので、それに頼るのは危険すぎます。

楽をしようとして何かあったら、結局、地道にやっておけば良かったと後悔する事になりますよ。

投稿2021/07/09 11:22

編集2021/07/09 11:41
sazi

総合スコア25327

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

「1セットの中に同じ商品だけ2つ以上含まれており、誤ったDB更新の結果、以下のようなデータができてしまった」ということがありえない前提をとります。

商品ID発注番号
EEEEEEEEEEEEEEEE8
EEEEEEEEEEEEEEEE8
EEEEEEEEEEEEEEEE9
EEEEEEEEEEEEEEEE9

この場合、以下のようなクエリで処理できるとは思います。

SQL

1WITH U AS ( 2 SELECT 3 T1.商品ID, 4 T1.発注番号, 5 MOD(DENSE_RANK() OVER (PARTITION BY T2.商品IDリスト ORDER BY T1.発注番号) - 1, ARRAY_LENGTH(T2.商品IDリスト, 1)) + 1 AS RNK1, 6 ROW_NUMBER() OVER (PARTITION BY T1.発注番号 ORDER BY T1.商品ID) AS RNK2 7 FROM T AS T1 8 JOIN ( 9 SELECT 発注番号, ARRAY_AGG(商品ID ORDER BY 商品ID) AS 商品IDリスト 10 FROM T 11 GROUP BY 発注番号 12 ) AS T2 ON T1.発注番号 = T2.発注番号 13) 14DELETE 15FROM T 16WHERE EXISTS ( 17 SELECT * 18 FROM U 19 WHERE T.商品ID = U.商品ID 20 AND T.発注番号 = U.発注番号 21 AND U.RNK1 <> U.RNK2 22)

個人的な意見を言うと、SQL一発で処理をせずに、スクリプト言語か何かでロジックを組んで処理したほうが良いかとは思います。

投稿2021/07/09 10:53

neko_the_shadow

総合スコア2349

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m6159

2021/07/12 09:12

すごいです、重複した発注番号毎に結合した商品ID配列をJOINして集計関数で2通りの番号を振って一致したもの以外を除外する方法で条件を満たせるのですね、非常に参考になりました。 可能であればお聞きしたいのですが MOD(DENSE_RANK() OVER (PARTITION BY T2.商品IDリスト ORDER BY T1.発注番号) - 1, ARRAY_LENGTH(T2.商品IDリスト, 1)) + 1 AS RNK1 の部分をDENSE_RANK() OVER (PARTITION BY T2.商品IDリスト ORDER BY T1.発注番号)ではなく上記の記載にした理由をお聞きしたいのですが、どのような場合に違いが出るのでしょうか。
sazi

2021/07/12 09:34 編集

@m6159さん ピックアップの為にselectするなら良いですけど、いきなりDELETEされてしまうような事だけは避けた方が良いですよ。
neko_the_shadow

2021/07/12 15:24

同じセットを複数回発注した場合にうまく処理するためのものです。たとえば以下のようなデータ対策となります。 (商品ID, 発注番号) = (AAA, 1), (BBB, 1), (AAA, 2), (BBB, 2), (AAA, 10), (BBB, 10), (AAA, 11), (BBB, 11)
m6159

2021/07/13 10:35

なるほど!理解できました。 追加の質問まで回答頂き誠にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問