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

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

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

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

Q&A

解決済

2回答

3685閲覧

sqlの結果を列にして集計データを表示したい

enigumalu

総合スコア192

SQL

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

0グッド

0クリップ

投稿2017/02/07 02:14

編集2017/02/07 04:22

下記のSQLを実行して月ごとに3回以上エントリーしたユーザ
を表示するようにしたのですがこの時、月に何回表示されたかをSQLの結果で列で表示したいのですが、重複が完全に削除されてしまい最後に3回を超えたエントリーしか表示されないのですが何がいけないのでしょうか。

select tmp.id as 'ID' , case when tmp.id_class = 1 then ‘ジョブ1’ else ‘ノーマル’ end as クラス, case tmp.month when 201611 then tmp.count else ifnull(null,'0') end as '201611', case tmp.month when 201612 then tmp.count else ifnull(null,'0') end as '201612', case tmp.month when 201701 then tmp.count else ifnull(null,'0') end as '201701' from ( select id, DATE_FORMAT(rest_date, "%Y%m") month, id_class, count(id) as count from ent.test_rest where id is not null and '2016-11-01 00:00:00' < up_date and up_date < '2017-01-31 23:59:59’ GROUP BY DATE_FORMAT(reserve_date, "%Y%m"), id HAVING count >= 3 ORDER BY id ASC ) tmp group by tmp.id

ほしい結果例
id,クラス,201611,201612,201701
a111,ジョブ1,0,3,5
a222,ノーマル,0,0,6
a333,ノーマル,14,0,3

DBのイメージ
pid id rest_date up_date
15 aaa1 2016-11-01 00:00:00 2016-11-01 00:00:00
16 aaa1 2016-11-02 00:00:00 2016-11-02 00:00:00
17 aaa1 2016-11-13 00:00:00 2016-11-13 00:00:00
18 aaa1 2016-11-16 00:00:00 2016-11-16 00:00:00
19 ccc3 2016-11-02 00:00:00 2016-11-02 00:00:00
20 ccc3 2016-11-02 00:00:00 2016-11-02 00:00:00
21 ccc3 2016-11-02 00:00:00 2016-11-02 00:00:00
22 bbb2 2016-12-01 00:00:00 2016-12-01 00:00:00
23 bbb2 2016-12-02 00:00:00 2016-12-02 00:00:00
24 bbb2 2016-12-03 00:00:00 2016-12-03 00:00:00
25 bbb2 2016-12-04 00:00:00 2016-12-04 00:00:00
26 aaa1 2017-01-09 00:00:01 2017-01-09 00:00:00
27 aaa1 2017-01-10 00:00:01 2017-01-10 00:00:00
28 aaa1 2017-01-18 00:00:01 2017-01-18 00:00:00
29 bbb2 2017-01-23 00:00:01 2017-01-23 00:00:00
30 bbb2 2017-01-24 00:00:01 2017-01-24 00:00:00
31 bbb2 2017-01-25 00:00:01 2017-01-25 00:00:00
32 bbb2 2016-12-04 00:00:00 2016-12-04 00:00:00
33 ccc3 2017-01-08 00:00:01 2017-01-08 00:00:00
34 ccc3 2017-01-08 00:00:01 2017-01-09 00:00:00
35 ccc3 2017-01-08 00:00:01 2017-01-08 00:00:00

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

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

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

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

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

yambejp

2017/02/07 02:28

SQLの種類はなんでしょう?それと結果に対する元データはどんなデータなのか追記お願いします
enigumalu

2017/02/07 04:22

mysqlです元データも追記しました
guest

回答2

0

ベストアンサー

例示を元にやってみました

  • 元データ

SQL

1create table test_rest(pid int, id varchar(10),rest_date datetime, up_date datetime); 2insert into test_rest values 3(15,'aaa1','2016-11-01 00:00:00','2016-11-01 00:00:00'), 4(16,'aaa1','2016-11-02 00:00:00','2016-11-02 00:00:00'), 5(17,'aaa1','2016-11-13 00:00:00','2016-11-13 00:00:00'), 6(18,'aaa1','2016-11-16 00:00:00','2016-11-16 00:00:00'), 7(19,'ccc3','2016-11-02 00:00:00','2016-11-02 00:00:00'), 8(20,'ccc3','2016-11-02 00:00:00','2016-11-02 00:00:00'), 9(21,'ccc3','2016-11-02 00:00:00','2016-11-02 00:00:00'), 10(22,'bbb2','2016-12-01 00:00:00','2016-12-01 00:00:00'), 11(23,'bbb2','2016-12-02 00:00:00','2016-12-02 00:00:00'), 12(24,'bbb2','2016-12-03 00:00:00','2016-12-03 00:00:00'), 13(25,'bbb2','2016-12-04 00:00:00','2016-12-04 00:00:00'), 14(26,'aaa1','2017-01-09 00:00:01','2017-01-09 00:00:00'), 15(27,'aaa1','2017-01-10 00:00:01','2017-01-10 00:00:00'), 16(28,'aaa1','2017-01-18 00:00:01','2017-01-18 00:00:00'), 17(29,'bbb2','2017-01-23 00:00:01','2017-01-23 00:00:00'), 18(30,'bbb2','2017-01-24 00:00:01','2017-01-24 00:00:00'), 19(31,'bbb2','2017-01-25 00:00:01','2017-01-25 00:00:00'), 20(32,'bbb2','2016-12-04 00:00:00','2016-12-04 00:00:00'), 21(33,'ccc3','2017-01-08 00:00:01','2017-01-08 00:00:00'), 22(34,'ccc3','2017-01-08 00:00:01','2017-01-09 00:00:00'), 23(35,'ccc3','2017-01-08 00:00:01','2017-01-08 00:00:00');

これをidと月ごとに集計して、idごとに横に集計するんですよね?
こんな感じでしょうか?

SQL

1select id 2,sum(c*(month='201611')) as `201611` 3,sum(c*(month='201612')) as `201612` 4,sum(c*(month='201701')) as `201701` 5from( 6select id,DATE_FORMAT(rest_date, "%Y%m") month ,count(*) as c 7from test_rest 8group by id,month 9having c>=3 10) as sub 11group by id 12

見た感じ、全部のデータが3以上になっている例のようなので
2以下を切り捨てられていません

投稿2017/02/07 04:50

yambejp

総合スコア114767

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

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

enigumalu

2017/02/07 08:38

ありがとうございます。最後のところにHAVINGつけてあげれば欲しい形式で取得できました having `201611`>=3 or `201612`>=3 or `201701`>=3
guest

0

sql

1SELECT 2 r.id, 3 r.id_class AS `クラス`, 4 IFNULL(tmp_201611.count, 0) AS `201611`, 5 IFNULL(tmp_201612.count, 0) AS `201612`, 6 IFNULL(tmp_201701.count, 0) AS `201701` 7FROM 【id, id_class のマスターとなるテーブル】 AS r 8LEFT OUTER JOIN ( 9 SELECT id, COUNT(*) AS count 10 FROM test_rest 11 WHERE id IS NOT NULL 12 AND up_date >= '2016-11-01 00:00:00' 13 AND up_date < '2016-12-01 00:00:00' 14 GROUP BY id 15) AS tmp_201611 16ON r.id = tmp_201611.id 17LEFT OUTER JOIN ( 18 SELECT id, COUNT(*) AS count 19 FROM test_rest 20 WHERE id IS NOT NULL 21 AND up_date >= '2016-12-01 00:00:00' 22 AND up_date < '2017-01-01 00:00:00' 23 GROUP BY id 24) AS tmp_201612 25ON r.id = tmp_201612.id 26LEFT OUTER JOIN ( 27 SELECT id, COUNT(*) AS count 28 FROM test_rest 29 WHERE id IS NOT NULL 30 AND up_date >= '2017-01-01 00:00:00' 31 AND up_date < '2017-02-01 00:00:00' 32 GROUP BY id 33) AS tmp_201701 34ON r.id = tmp_201701.id 35WHERE tmp_201611.count >= 3 36 OR tmp_201612.count >= 3 37 OR tmp_201701.count >= 3;

SQL中の【id, id_class のマスターとなるテーブル】 部分には、ユーザのマスターとなるテーブル(idおよびid_classカラムが定義されているもの)を指定してください。

ただし、テーブル定義等を提示いただいていないため、動作確認等は一切しておりません。

追記および修正

マスターとなるテーブルはなく1つのテーブルのみになります。

では、どのようにしてユーザを管理しているのですか?
カラム名は異なるとしても、'aaa1'や'ccc3'などの値をプライマリキーとして保持しているテーブルがあるはずです。
そのテーブル名を指定してください。

以下、masterという名称のユーザーのマスターテーブルが存在する前提の回答を提示させていただきます。

sql

1SELECT 2 r.id, 3 CASE r.id_class WHEN 1 THEN 'ジョブ1' ELSE 'ノーマル' END AS `クラス`, 4 IFNULL(tmp_201611.count, 0) AS `201611`, 5 IFNULL(tmp_201612.count, 0) AS `201612`, 6 IFNULL(tmp_201701.count, 0) AS `201701` 7FROM master AS r 8LEFT OUTER JOIN ( 9 SELECT id, COUNT(*) AS count 10 FROM test_rest 11 WHERE id IS NOT NULL 12 AND up_date >= '2016-11-01 00:00:00' 13 AND up_date < '2016-12-01 00:00:00' 14 GROUP BY id 15) AS tmp_201611 16ON r.id = tmp_201611.id 17LEFT OUTER JOIN ( 18 SELECT id, COUNT(*) AS count 19 FROM test_rest 20 WHERE id IS NOT NULL 21 AND up_date >= '2016-12-01 00:00:00' 22 AND up_date < '2017-01-01 00:00:00' 23 GROUP BY id 24) AS tmp_201612 25ON r.id = tmp_201612.id 26LEFT OUTER JOIN ( 27 SELECT id, COUNT(*) AS count 28 FROM test_rest 29 WHERE id IS NOT NULL 30 AND up_date >= '2017-01-01 00:00:00' 31 AND up_date < '2017-02-01 00:00:00' 32 GROUP BY id 33) AS tmp_201701 34ON r.id = tmp_201701.id 35WHERE tmp_201611.count >= 3 36 OR tmp_201612.count >= 3 37 OR tmp_201701.count >= 3;

試しに叩いてみたのですが、3件以下も検出されました

とのことですが、SQLFiddle の実行結果の通り、意図通りの結果が得られるはずです。
http://sqlfiddle.com/#!9/efd896/1

もし、本当に

マスターとなるテーブルはなく1つのテーブルのみ

であれば、これ以上のことは私には分かりません。

投稿2017/02/07 03:40

編集2017/02/07 06:10
KiyoshiMotoki

総合スコア4791

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

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

enigumalu

2017/02/07 04:24

マスターとなるテーブルはなく1つのテーブルのみになります。 試しに叩いてみたのですが、3件以下も検出されました
KiyoshiMotoki

2017/02/07 06:11

返信ありがとうございます。 とりあえず、「マスターとなるテーブル」が存在する前提で、回答欄に修正版の回答を追記させていただきました。 ご確認ださい。 あと、質問欄にご提示いただいた「DBのイメージ 」に'id_class'が存在しません。 提示する情報は下手に編集したり要約したりせず、可能な限り「そのまま」提示してください。 https://teratail.com/help/question-tips#questionTips3-4
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問