teratail header banner
teratail header banner
質問するログイン新規登録

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

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

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

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

Q&A

解決済

2回答

476閲覧

SQLにおけるデータが存在しない場合の差分の取得について(在庫等)

okkoto

総合スコア2

PostgreSQL

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

0グッド

0クリップ

投稿2022/02/15 05:48

編集2022/02/15 05:49

0

0

一定期間毎の差分を取得するためにWithを利用して取得を試みたが、対象データの一部が存在しない場合差分が取れないため解消したいと考えております。何か良い方法がありましたらご助力頂けると幸いです。


サンプル

PostgreSQL

1CREATE TABLE zaikoTable( 2id integer not null, 3 zaiko integer not null, 4 date date not null ); 5 6INSERT INTO zaikotable VALUES(1,100,'2021-01-01'); 7INSERT INTO zaikotable VALUES(1,150,'2021-02-01'); 8INSERT INTO zaikotable VALUES(1,130,'2021-03-01'); 9INSERT INTO zaikotable VALUES(2,100,'2021-01-01'); 10INSERT INTO zaikotable VALUES(2,95,'2021-02-01'); 11INSERT INTO zaikotable VALUES(2,90,'2021-03-01'); 12INSERT INTO zaikotable VALUES(3,100,'2021-01-01'); 13INSERT INTO zaikotable VALUES(3,80,'2021-02-01'); 14INSERT INTO zaikotable VALUES(3,120,'2021-03-01'); 15INSERT INTO zaikotable VALUES(4,100,'2021-02-01'); 16INSERT INTO zaikotable VALUES(4,110,'2021-03-01');

※id:4 は2021/1/1のデータが存在しないものとします

idzaikodate
11002021-01-01
11502021-02-01
11302021-03-01
21002021-01-01
2952021-02-01
2902021-03-01
31002021-01-01
3802021-02-01
31202021-03-01
41002021-02-01
41102021-03-01

取得したい値
2021/3/1を基準に2/1、1/1のデータと数量を比較します
このときid:4の1/1時点のデータを0として差分を取得させたい

iddiff 1monthdiff 2month
1-2030
2-5-10
34020
410110

差分取得
2021/3/1を基準に2/1、1/1のデータと数量を比較します

PostgreSQL

1With g0 As( 2 SELECT id, zaiko, date 3 FROM ZaikoTable 4 WHERE date = '2021/3/1' 5) , g1 As( 6 SELECT id, zaiko, date 7 FROM ZaikoTable 8 WHERE date = '2021/2/1' 9) ,g2 As( 10 SELECT id, zaiko, date 11 FROM ZaikoTable 12 WHERE date = '2021/1/1' 13) 14SELECT 15 g0.id, 16 g0.zaiko - g1.zaiko As "diff 1month", 17 g0.zaiko - g2.zaiko As "diff 2month" 18FROM g0, g1, g2 19WHERE g0.id = g1.id AND g0.id = g2.id ;

実行結果
whereで全て等式を条件にした結果全ての1/1、2/1、3/1すべてのデータが存在しないと出力されない結果となる

iddiff 1monthdiff 2month
1-2030
2-5-10
34020

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

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

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

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

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

guest

回答2

0

こういうのはどうでしょうか。

SELECT DISTINCT id FROM ZaikoTable でZaikoTableに存在する全てのidが得られますよね。
その結果を使って、データがほしい日付をカラムに加えて、

SQL

1select z.id, '2021/1/1' as "date" 2from (select distinct id from ZaikoTable) as z

これとまた ZaikoTable と突き合わせて、

SQL

1select zz.id, zz.date, coalesce(zt.zaiko, 0) as zaiko 2from ( 3 select z.id, '2021/1/1' as "date" 4 from (select distinct id from ZaikoTable) as z 5) as zz 6left join ( 7 select id, "date", zaiko 8 from ZaikoTable 9 where "date" = '2021/1/1' 10) as zt on .id = zt.id and zz.date = zt.date

とすると、在庫データがないところも0が詰められます。
(実行していない机上のコードなので、ミスありましたらご指摘ください。)

投稿2022/02/15 07:01

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

okkoto

2022/02/15 10:43

回答ありがとうございました サブクエリでの処理も考えたのですがカラムが増えると複雑になって断念していたところでした。 idだけ全体から抽出してしまえば結合で対応出来そうですね。
guest

0

ベストアンサー

zaikoカラムには0以上の値が入っているという前提に立つと、以下のようなSQLで実現できるかと思います。

SQL

1SELECT 2 id, 3 MAX(CASE WHEN date = '2021-03-01' THEN zaiko ELSE 0 END) - MAX(CASE WHEN date = '2021-02-01' THEN zaiko ELSE 0 END) AS "diff 1month", 4 MAX(CASE WHEN date = '2021-03-01' THEN zaiko ELSE 0 END) - MAX(CASE WHEN date = '2021-01-01' THEN zaiko ELSE 0 END) AS "diff 2month" 5FROM zaikotable 6GROUP BY id 7ORDER BY id

投稿2022/02/15 09:47

neko_the_shadow

総合スコア2395

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

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

okkoto

2022/02/15 10:37

確かにMAXとCASE WHENでシンプルに処理できますね! zaikoは0以上の自然数となるので回答の形式で対応可能です。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問