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

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

新規登録して質問してみよう
ただいま回答率
85.46%
Oracle Database

Oracle Databaseは、米オラクルが開発・販売を行うリレーショナルデータベース管理システムです。

SQL

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

Q&A

解決済

3回答

1103閲覧

SQLでCOUNTごとに取得するデータを変更したい

UmiSea2

総合スコア1

Oracle Database

Oracle Databaseは、米オラクルが開発・販売を行うリレーショナルデータベース管理システムです。

SQL

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

0グッド

0クリップ

投稿2021/02/01 18:34

編集2021/02/02 03:20

データベースの環境はOracle 11gとなります。

前提・実現したいこと

現在下記のようなテーブルにて、カウント数ごとのデータを取得したいと考えています。
具体的には、1つの下記のようにテーブルにカラムがあります。

テストテーブル
...............
ユーザーID
KJコード
PGコード
ステータスコード
..................

SQL

1CREATE TABLE TEST 2( 3 USER_ID VARCHAR(10) 4 ,KJ_CODE NUMBER 5 ,PG_CODE NUMBER 6 ,STATUS_CODE NUMBER 7);

このとき、ステータスコードには1~4のコードが登録されています。

SQL

1INSERT INTO TEST(USER_ID, KJ_CODE,PG_CODE,STATUS_CODE ) VALUES ('0010',1234,1111,1) ; 2INSERT INTO TEST(USER_ID, KJ_CODE,PG_CODE,STATUS_CODE ) VALUES ('0010',1234,1112,2) ; 3INSERT INTO TEST(USER_ID, KJ_CODE,PG_CODE,STATUS_CODE ) VALUES ('0010',1234,1113,3) ; 4INSERT INTO TEST(USER_ID, KJ_CODE,PG_CODE,STATUS_CODE ) VALUES ('0010',1234,1114,4) ; 5INSERT INTO TEST(USER_ID, KJ_CODE,PG_CODE,STATUS_CODE ) VALUES ('0010',1234,1115,1) ; 6INSERT INTO TEST(USER_ID, KJ_CODE,PG_CODE,STATUS_CODE ) VALUES ('0010',1234,1116,1) ; 7INSERT INTO TEST(USER_ID, KJ_CODE,PG_CODE,STATUS_CODE ) VALUES ('0010',1234,1117,2) ; 8INSERT INTO TEST(USER_ID, KJ_CODE,PG_CODE,STATUS_CODE ) VALUES ('0010',4321,1111,1) ; 9INSERT INTO TEST(USER_ID, KJ_CODE,PG_CODE,STATUS_CODE ) VALUES ('0010',4321,1112,1) ; 10INSERT INTO TEST(USER_ID, KJ_CODE,PG_CODE,STATUS_CODE ) VALUES ('0010',4321,1113,2) ; 11INSERT INTO TEST(USER_ID, KJ_CODE,PG_CODE,STATUS_CODE ) VALUES ('0010',4321,1114,2) ; 12INSERT INTO TEST(USER_ID, KJ_CODE,PG_CODE,STATUS_CODE ) VALUES ('0010',4321,1115,3) ;

そして、KJコードをGROUP BYで集約しつつPG_CODEをCOUNTした合計数と、
ステータスコード1~4のそれぞれのCOUNTした数をだし、
ステータスコード1~4それぞれのCOUNTした数とPG_CODEをCOUNTした数、
あるいはステータスコードの合計を例えば下記のように比較します。

ステータスコードの値1の合計数 > PG_CODEの合計数
ステータスコードの値1の合計数 < ステータスコードの値2の合計数
ステータスコードの値3の合計数 > 0
ステータスコードの値4の合計数 < PG_CODEの合計数

そのうえで最終的に、
ユーザーID、GROUP BYしたKJコード、CASEか何かで比較したステータスコード
のデータを取得したいです。

KJ_CODEごとにSTATUS_CODE の一番数が多いもの、あるいは1個以上ある場合など
例えば、サンプルデータでKJ_CODEが1234のとき、
status1の数が KJ_CODE(1234)のPG_CODE数より大きいとstatus1を表示
status2の数が1個以上のときはstatus2を表示、ということを想定しています。

発生している問題

初歩的で申し訳ありませんが、一つのテーブルでGROUP BYしつつ、
上記のように二つの列をカウントするような記述がよくわかっていません。
こういった場合は、やはり同一テーブルを副問い合わせなどするのでしょうか。
組み方、考え方をご教授頂けますと幸いです。

現在私自身は、下記のようなSQLの記述状況で手間取ってしまっています。

SQL

1SELECT 2,USER_ID 3,KJ_CODE 4,COUNT(PG_CODE) 5,COUNT(STATUS_CODE) 6FROM 7TEST 8GROUP BY 9KJ_CODE

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

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

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

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

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

Orlofsky

2021/02/01 18:44 編集

GROUP BY の空白は勝手に省略するとエラーになりますから、省略しないでください。 スペルは見直してね。 質問は修正できます。
Orlofsky

2021/02/01 18:46

同じSQLでもデータベースやそのバージョンによって方言が大きいですから、どのデータベースを使うのかを質問のタグで示したり、質問にバージョンも明記した方が適切なコメントが付き易いです。
Orlofsky

2021/02/01 18:51

ここの掲示板ではMarkdownの使い方を覚えてください。 テーブル定義はCREATE TABLE文で、テーブル中のデータはINSERT文で https://teratail.com/help/question-tips#questionTips3-7 の [コード] に修正できるとSQLの動作確認が容易になるので、適切なコメントが付き易くなります。
m.ts10806

2021/02/01 22:22

細かくて申し訳ないですが、冒頭の挨拶はなくていいです。 淡々と要件のみ記載してください。
sousuke

2021/02/02 01:44

「KJコードをCOUNTした数」っていうのはサンプルデータだといくつになるのか、その理由を伝えたほうがいいと思います。
sazi

2021/02/02 02:49

集計の単位がいまいちよく分かりません。 サンプルデータを元に、どういう結果を取得されたいのかを追記された方が良いと思います。
退会済みユーザー

退会済みユーザー

2021/02/02 02:58

「Oracle Database」ってタグがあるので付けてください。 質問がより詳しい方の目に留まるようになります。(回答がもらえること、解決することは別)
UmiSea2

2021/02/02 09:09

ご指摘のほどありがとうございました。
Orlofsky

2021/02/02 19:02

集計し易さを考えたコード設計にしようって考えた方が良いかも?
guest

回答3

0

ベストアンサー

SQL

1SELECT USER_ID, KJ_CODE, COUNT(*) kj_count 2 , sum(case when STATUS_CODE=1 then 1 else 0 end) status1_count 3 , sum(case when STATUS_CODE=2 then 1 else 0 end) status2_count 4 , sum(case when STATUS_CODE=3 then 1 else 0 end) status3_count 5 , sum(case when STATUS_CODE=4 then 1 else 0 end) status4_count 6FROM TEST 7GROUP BY USER_ID, KJ_CODE

加工するなら

SQL

1select USER_ID, KJ_CODE 2 , case when status1_count > kj_count then 'XXX' end 3from ( 4 SELECT USER_ID, KJ_CODE, COUNT(*) kj_count 5 , sum(case when STATUS_CODE=1 then 1 else 0 end) status1_count 6 , sum(case when STATUS_CODE=2 then 1 else 0 end) status2_count 7 , sum(case when STATUS_CODE=3 then 1 else 0 end) status3_count 8 , sum(case when STATUS_CODE=4 then 1 else 0 end) status4_count 9 FROM TEST 10 GROUP BY USER_ID, KJ_CODE 11)

投稿2021/02/02 03:09

sazi

総合スコア25206

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

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

UmiSea2

2021/02/02 03:16

ご回答ありがとうございます。サンプルテーブルの項目が一つ足りなかったため、さきほど修正いたましたが、項目を変更して確認させていただきます。
UmiSea2

2021/02/02 09:10

ありがとうございました。無事想定されている動作を組むことができました。
guest

0

そのうえで最終的に、ユーザーID、GROUP BYしたKJコード、CASEか何かで比較したステータスコードのデータを取得したいです。

user_idとkj_codeごとに、ステータス1~4がそれぞれいくつあるかを数えたいということであっていますか?

であれば、以下のようなSQLで実現できるかと思います。

SQL

1SELECT 2 user_id, 3 kj_code, 4 COUNT(status_code=1 OR NULL) AS status1, 5 COUNT(status_code=2 OR NULL) AS status2, 6 COUNT(status_code=3 OR NULL) AS status3, 7 COUNT(status_code=4 OR NULL) AS status4 8FROM TEST 9GROUP BY user_id, kj_code

この実行結果は以下のようになります。

user_idkj_codestatus1status2status3status4
001043212210
001012342221

投稿2021/02/02 01:25

neko_the_shadow

総合スコア2273

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

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

UmiSea2

2021/02/02 02:39

ご回答ありがとうございます。わかりにくい質問ですいません。 想定は、KJ_CODEが仮に二種類あると二件のデータが取得される想定です。 KJ_CODEごとにSTATUS_CODE の一番数が多いもの、あるいは1個以上ある場合など 例えば、サンプルデータでKJ_CODEが1234のとき、 status1の数が KJ_CODE(1234)の数より大きいとstatus1を表示 status2の数が1個以上のときはstatus2を表示、ということを想定している状態です。
sazi

2021/02/02 03:05 編集

@UmiSea2さん この回答のSQLで条件判断するための情報は取得できると思うのですが? Caseでの判断などは、上記をインラインビューにしてネストさせて行えば良いのでは? @neko_the_shadowさん よく見ると、真偽をカウントしているので、駄目な気がします。 その前に、oracleではエラーですが。
guest

0

テータベースによっては、GROUP BY と共に、ROLLUP, CUBE 辺りを使うといい場合ものあります。

投稿2021/02/01 18:50

Orlofsky

総合スコア16415

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

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

UmiSea2

2021/02/02 00:00

ありがとうございます。確認させていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問