質問するログイン新規登録
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

PostgreSQL

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

Q&A

解決済

3回答

2427閲覧

SQLで重複キーを探して重複していないキーを合わせた後、削除

durasama

総合スコア18

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

PostgreSQL

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

0グッド

0クリップ

投稿2019/02/27 02:45

0

0

前提・実現したいこと

PostgreSQLで一部キーが重複していた場合
重複していないキー(数字)を足す処理を行いたいです

例えばtestテーブルが存在し

id,date,num0,num1,num2 1,2019-02-25,0,1,0 1,2019-02-25,1,0,0 1,2019-02-26,3,1,2 2,2019-02-25,0,0,1 2,2019-02-25,0,2,0

というテーブルがあったとして、実行後

id,date,num0,num1,num2 1,2019-02-25,1,1,0 1,2019-02-26,3,1,2 2,2019-02-25,0,2,1

上記の様に、id,dateを重複キーとして絞り出し重複していない箇所を合わせるようにし、
重複していたレコードは削除するように行いたいと思っております。

id,dateが重複しているのにも関わらず同じnumに0以外の数字が入ることはありません
例えば

id,date,num0,num1,num2
1,2019-02-25,0,1,0
1,2019-02-25,1,1,0

このように`id`と`data`は重複しているが、両方とも`num1`に0以外の数字が入っている というようなレコードは存在しません。 上記SQLの作成にご教授頂けないでしょうか。 ### 該当のソースコード ```sql SELECT id,date FROM test GROUP BY id,date HAVING COUNT(*)>1

試したこと

Update文を使って更新処理を行おうとしましたが知恵が足らずうまく動きませんでした。

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

Windows 10
PostgreSQL11

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

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

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

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

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

guest

回答3

0

ベストアンサー

既に元のテーブルがない場合を考慮し、一応普通に処理するSQLも書いておきました。

個人的に同一表の書き換えは順序を保証できる方法がない限り、無理だと思っています。今回だと全カラムでソートしたものを使う他ありませんが、内部に相当大きな一時表をハッシュ込みで複数作らせるだけなので、別表のアプローチにしています。要件からは外れているので、気に入らない場合は破棄してください。
データ量が多い場合は、ctas後にtestchangeのID/日付にインデックスを付けといた方がいいです。

SQL

1create table test(id int,date date,num0 int,num1 int,num2 int); 2 3insert into test values 4(1,'2019-02-25',0,1,0), 5(1,'2019-02-25',1,0,0), 6(1,'2019-02-26',3,1,2), 7(2,'2019-02-25',0,0,1), 8(2,'2019-02-25',0,2,0); 9commit; 10 11create table testchange as select id, date, max(num0) as num0, max(num1) as num1, max(num2) as num2 from test group by id, date having count(*) > 1; 12 13delete from test a where exists(select 'x' from testchange where id=a.id and date=a.date); 14insert into test select * from testchange; 15commit; 16 17drop table testchange; 18vacuum test; 19

投稿2019/02/27 08:20

wwbQzhMkhhgEmhU

総合スコア343

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

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

0

それって、元質問(PostgreSQLで別テーブルに変換するInsert文)の回答の不備ですね。

group byの考慮が漏れてました。
NUMはidとdatetime::dateと時間帯で複数はない前提でMAX()としています。

SQL

1insert into b 2select id, datetime ::date 3 , max(case when date_part('hour',datetime)=0 then num else 0 end) -- num_00 4-- ~略~ 5 , max(case when date_part('hour',datetime)=23 then num else 0 end) -- num_23 6from a 7group by id, datetime ::date 8order by id, datetime

投稿2019/02/27 03:25

sazi

総合スコア25430

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

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

0

データを更新しつついらないデータを削除することはできないので

  • 更新してから削除するか
  • viewを利用して削除処理はしない

のどちらかが有効だと思います
単純に表示だけならこんな感じ

SQL

1create table tbl(pkey int primary key,id int,d date,num0 int,num1 int,num2 int); 2insert into tbl values 3(1,1,'2019-02-25',0,1,0), 4(2,1,'2019-02-25',1,0,0), 5(3,1,'2019-02-26',3,1,2), 6(4,2,'2019-02-25',0,0,1), 7(5,2,'2019-02-25',0,2,0); 8 9select id,d,sum(num0) as num0,sum(num1) as num1,sum(num2) as num2 10from tbl 11group by id,d; 12

投稿2019/02/27 03:07

yambejp

総合スコア117975

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問