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

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

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

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

Q&A

解決済

1回答

828閲覧

過去5年間の移動年計を出したい

退会済みユーザー

退会済みユーザー

総合スコア0

PostgreSQL

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

0グッド

0クリップ

投稿2018/06/12 10:47

編集2018/06/12 11:03

前提・実現したいこと

PostgreSQLのデータベースにある、
売上伝票データの収まるテーブルを使って、
1年間の買上金額を基にランク分けして、
A,B,C,Zランクに何人いて買上額がいくらなのか、
これを過去5年間月単位の移動年計にしようとして躓いています。

指定日を基準に過去1年間に対するデータを抽出するSELECT文が出来上がっています。
これに、generate_series関数を組み合わせて基準日をスライドさせれば
移動年計になると思いついたのですが。

指定日を基準日としたランク&買上額集計SQL

カラム意味
jrn_kyk_cdinteger顧客コード
jrn_syo_gakinteger買上額(売上時は正、売上取消は負)
jrn_dnp_nmtext伝票名、売上と客返(売上取消)
jrn_ins_ymdtimestamptz記録日時(create_atみたいなもの)

※ 売上の取消ではレコード削除が行われず、売上と逆のマイナス金額が入力される。

SQL

1select j.k_rank, count(j.jrn_kyk_cd) as k_count, sum(j.syo_gak) as gak 2from ( 3 select jrn_kyk_cd, sum(jrn_syo_gak) as syo_gak, rank() over (order by sum(jrn_syo_gak) desc) as rnk, case when sum(jrn_syo_gak) >= 300000 then 'A' when sum(jrn_syo_gak) >= 200000 then 'B' when sum(jrn_syo_gak) >= 100000 then 'C' else 'Z' end as k_rank 4 from jrn_tbl 5 where jrn_pst_cd = 1 and (jrn_dnp_nm = '売上' or jrn_dnp_nm = '客返') and jrn_ins_ymd between '2017-06-01+09'::timestamptz and '2018-06-01+09'::timestamptz 6 group by jrn_kyk_cd 7) as j 8group by j.k_rank 9order by j.k_rank

試したこと

これを拡張して、

SQL

1select s.a, j.k_rank, count(j.jrn_kyk_cd) as k_count, sum(j.syo_gak) as gak 2from ( 3 select s.a, jrn_kyk_cd, sum(jrn_syo_gak) as syo_gak, rank() over (order by sum(jrn_syo_gak) desc) as rnk, case when sum(jrn_syo_gak) >= 300000 then 'A' when sum(jrn_syo_gak) >= 200000 then 'B' when sum(jrn_syo_gak) >= 100000 then 'C' else 'Z' end as k_rank 4 from jrn_tbl 5 where jrn_pst_cd = 1 and (jrn_dnp_nm = '売上' or jrn_dnp_nm = '客返') and jrn_ins_ymd between s.a + '-1 year'::interval and s.a 6 group by s.a, jrn_kyk_cd 7) as j, ( 8 select a 9 from generate_series('2018-06-01+09'::timestamptz, '2018-06-01+09'::timestamptz + '-5 years'::interval, '-1 month'::interval) as a 10) as s 11group by s.a, j.k_rank 12order by s.a, j.k_rank

などと以前作ったクエリーからgenerate_series関数を試しに組み合わせてみたものの、

SQL : missing FROM-clause entry for table "s"

などと。

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

PostgreSQL 9.6.8

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

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

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

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

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

guest

回答1

0

ベストアンサー

質問文を起こしている最中に自己解決しちゃったので、
せっかく書いた質問文がもったいないから、
自己解決として投稿しておきます。

SQL

1select j.a, j.k_rank, count(j.jrn_kyk_cd) as k_count, sum(j.syo_gak) as gak 2from ( 3 select s.a, jrn_kyk_cd, sum(jrn_syo_gak) as syo_gak, rank() over (order by sum(jrn_syo_gak) desc) as rnk, case when sum(jrn_syo_gak) >= 300000 then 'A' when sum(jrn_syo_gak) >= 200000 then 'B' when sum(jrn_syo_gak) >= 100000 then 'C' else 'Z' end as k_rank 4 from jrn_tbl, ( 5 select a 6 from generate_series('2018-06-01+09'::timestamptz, '2018-06-01+09'::timestamptz + '-5 years'::interval, '-1 month'::interval) as a 7 ) as s 8 where jrn_pst_cd = 1 and (jrn_dnp_nm = '売上' or jrn_dnp_nm = '客返') and jrn_ins_ymd between s.a + '-1 year'::interval and s.a 9 group by s.a, jrn_kyk_cd 10) as j 11group by j.a, j.k_rank 12order by j.a, j.k_rank

投稿2018/06/12 10:48

編集2018/06/12 11:04
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問