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

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

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

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

Q&A

解決済

6回答

40359閲覧

SQL文でGROUP BYによる件数合計の合成出力の方法

seastar3

総合スコア2285

SQL

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

1グッド

0クリップ

投稿2016/10/31 15:08

編集2016/11/04 10:41

SQLのGroup by を使った件数カウントで行き詰まっていますので、ぜひお教え下さい。

部登録テーブル
生徒コード 性別コード 部コード
1101 1 5
1102 2 3
: : :

普通に男子の部ごとの人数であれば、
SELECT 部コード,COUNT(生徒コード) FROM 部登録テーブル WHERE 性別コード = 1 GROUP BY 部コード;
女子の部ごとの人数であれば、
SELECT 部コード,COUNT(生徒コード) FROM 部登録テーブル WHERE 性別コード = 2 GROUP BY 部コード;
のコードで以下のように出力できます。

部コード COUNT(生徒コード)
1 10
3 2
8 6
: :

実際これでPHPで実装し、MySQLから取り出しているのですが、全体のビューと男子のビューと女子のビューと切り替えて出力するだけではなく、次のように男女計を並べて出力するにはどう記述したらよいのでしょうか

部コード 男子計 女子計 合 計
1 10 0 10
2 0 15 15
3 2 6 8
: : : :

JOIN を使うのでしょうが、何回か挑戦しては挫折しています。よろしくお願いします。


皆様のおかげで無事実装できました。以下のように出るようになりました。

このやり方が10年以上分からなかったので,感無量です。
このテクニックを応用して、欠課レコードの科目別合計や得点レコードの科目別合計などに取り組んでみます。
回答していただいた皆様どうもありがとうございました。

yodel👍を押しています

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

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

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

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

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

guest

回答6

0

条件付き集計ですね。
割とよくやる機会は出てくるので割と情報も多かったりします。

よくあるパターンでは、
CASE式とSUM関数を組み合わせて実現します。
こちらの「異なる条件の集計を1つのSQLで行う」という項目の説明が、
正にやりたいことに該当するのではないでしょうか。

掲示したサイトは、
CASE式以外にも役立つノウハウが説明されており、
一読する価値があるので興味があれば他の項目も参照してみてください。

投稿2016/10/31 16:19

編集2016/10/31 16:21
Panzer_vor

総合スコア1636

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

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

seastar3

2016/10/31 16:38

Panzer_vorさん、早速にご回答ありがとうございます。 CASE句は使ったことがなかったので、自分の見識不足を痛感しています。 ご紹介のページを見ていると、大文字で長いコードの記述で、SQL文というよりは、COBOLプログラムを見ているような気がして、自称 昭和なプログラマー としてはほほ笑ましくなりました。 お勧めのように他の技術も読んでいきます。
guest

0

ベストアンサー

SQLの種類にもよりますが、trueを1とみなすものが多いことから
普通はこの手の集計はsumでちゃちゃっとやると思います

SQL

1select 部コード,sum(性別コード=1) as 男子計, sum(性別コード=2) as 女子計 ,count(*) 合計 2from 部登録テーブル group by 部コード;

ポイントはカウントするのですがsumを利用すること。
条件のない合計についてはcountを利用します

投稿2016/11/01 02:22

yambejp

総合スコア114747

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

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

seastar3

2016/11/01 04:32

動作しました。ありがとうございます。 WHERE 句で副問い合わせを使って学年別や運動部集計表や文化部集計表に使い分けたいので、シンプルなコードがありがたいです。
guest

0

動作未確認

sql

1select 部コード,COUNT(CASE WHEN 性別コード=1 THEN 1 ELSE null END) as boy,COUNT(CASE WHEN 性別コード=2 THEN 1 ELSE null END) as girl ,count(生徒コード) as total FROM 部登録テーブル GROUP BY 部コード;

こんな感じでとれませんか?

・表示がみにくいのでSQL分を`ではなく```で囲み直しました

投稿2016/10/31 15:21

編集2016/11/01 02:48
hiim

総合スコア1689

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

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

seastar3

2016/10/31 16:24

hiimさん、早速に回答頂きありがとうございます。 私はCASE句を今まで知りませんでした。尋ねてみるものですね。 明日、実装環境で確かめてみます。とりあえずお礼まで。
seastar3

2016/11/01 03:36

動作しました! ありがとうございます。
guest

0

UNIONを使ったSQLです。

sql

1SELECT 部コード,SUM(D) AS 男子計, SUM(J) AS 女子計, SUM(G) AS 合計 2FROM 3(SELECT 部コード,1 AS D ,0 AS J,1 AS G FROM 部登録テーブル WHERE 性別コード = 1 4UNION ALL 5SELECT 部コード,0,1,1 FROM 部登録テーブル WHERE 性別コード = 2 6) TB GROUP BY 1 ORDER BY 1

投稿2016/10/31 17:38

編集2016/11/01 02:02
A.Ichi

総合スコア4070

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

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

seastar3

2016/11/01 03:36

動作しました! ありがとうございます。
guest

0

SQL

1SELECT 2 部リスト.部コード, 3 ISNULL(男子集計.男子数, 0) AS 男子計, 4 ISNULL(女子集計.女子数, 0) AS 女子計, 5 ISNULL(男子集計.男子数, 0) + ISNULL(女子集計.女子数, 0) AS 合計 6FROM 7 ( 8 SELECT 9 DISTINCT 部コード 10 FROM 11 部登録テーブル 12 ) AS 部リスト 13 LEFT JOIN 14 ( 15 SELECT 16 部コード, 17 COUNT(生徒コード) AS 男子数 18 FROM 19 部登録テーブル 20 WHERE 21 性別コード = 1 22 GROUP BY 23 部コード 24 ) AS 男子集計 25 ON 部リスト.部コード = 男子集計.部コード 26 LEFT JOIN 27 ( 28 SELECT 29 部コード, 30 COUNT(生徒コード) AS 女子数 31 FROM 32 部登録テーブル 33 WHERE 34 性別コード = 2 35 GROUP BY 36 部コード 37 ) AS 女子集計 38 ON 部リスト.部コード = 女子集計.部コード

こんな感じでしょうか。
部リストはマスタテーブルがあるならそちらを利用した方が良いでしょう。

投稿2016/10/31 15:40

nakit

総合スコア410

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

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

seastar3

2016/10/31 16:29

nakitさん、早速に回答頂きありがとうございます。 実は半年ほど前、LEFT JOIN を使って試行錯誤し投げ出したもので、ふと思い立ってお尋ねした次第です。LEFT JOIN を組み込むとWHERE句に部登録テーブルを記述しないので奇妙な気がした覚えがあります。 ご指摘の通り、部マスタテーブルも存在します。それをWHERE句に適用すれば、0人の部もテーブルに表示できるのですね。 明朝、実装環境で確かめてみます。とりあえずお礼まで。
seastar3

2016/11/01 03:41

ちょっとフィールド名やエイリアスを対応させるのがまだうまくいっていないので、表示されません。さらに手当てしてやってみます。
guest

0

DecodeがOracle方言だった場合はご容赦ください。

SELECT
部コード,
SUM(DECODE(性別コード, 1, 1, 0)) "男子計",
SUM(DECODE(性別コード, 2, 1, 0)) "女子計"
FROM 部登録テーブル
GROUP BY 部コード;

投稿2016/11/01 03:58

YushiYamaguchi

総合スコア10

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

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

KiyoshiMotoki

2016/11/01 04:20

> DecodeがOracle方言だった場合はご容赦ください。 MySQL にも DECODE という名前の関数はありますが、用途が異なりますね。 https://dev.mysql.com/doc/refman/5.6/ja/encryption-functions.html#function_decode MySQL で同様のことを行なうには CASE 関数や IF 関数を使うか、 https://dev.mysql.com/doc/refman/5.6/ja/control-flow-functions.html#operator_case https://dev.mysql.com/doc/refman/5.6/ja/control-flow-functions.html#function_if yambejp様の回答のように単に  性別コード=1 とする方法がありますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問