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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

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

Q&A

解決済

3回答

5532閲覧

MySQL selectしている項目以外での並び替え

michael-ilcsy

総合スコア180

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

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

1グッド

0クリップ

投稿2018/05/31 13:53

MySQLの練習問題を解いていてわからない問題があります。 以下問題


社員情報テーブル(member)と部署情報テーブル(division)から「部署名」と「部署の人数」を部署IDの昇順で出力してください。

member

カラム名必須
member_idINTyes
nameVARCHAR(10)yes
division_idVARCHAR(10)yes

division

カラム名必須
division_idINTyes
division_nameVARCHARyes

出力例
営業部 2
人事部 2
システム部 6
総務部 2


一応自分で以下のようなコードを書いたのですが

SQL

1select c.division_name as '部署名' ,count(*) as '部署の人数' 2from ( 3select name , division_name ,b.division_id 4from member as a 5join division as b 6on a.division_id = b.division_id 7) as c 8group by c.division_name;

どうしても部署ID順にする方法が分かりません。
order byで出来ればいいのですが、出力には部署IDがないのでエラーはかれまくりました。
selectで選んでいる項目以外でのソートはどうやるものなんでしょうか?

papinianus👍を押しています

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

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

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

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

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

guest

回答3

0

ベストアンサー

groupb by を指定した時のselect やorder by項目はgroup byに項目を指定しなければなりません。

SQL

1select a.division_name as '部署名', count(member_id) as '部署の人数' 2from division as a 3 inner join member as b 4 on a.division_id = b.division_id 5group by a.division_id, a.division_name 6order by a.division_id 7;

投稿2018/05/31 15:16

sazi

総合スコア25138

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

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

michael-ilcsy

2018/05/31 15:28

回答ありがとうございます! 教えてもらったコードで思ったとおりに動きました。 group byに二つ設定したら(今回はidとnameが一対一対応してるから?)こんなにすっきり書けるんですね。勉強になりました
guest

0

こんな感じでしょうか?

sql

1select 2 (select diision_name from division where division_id = c.division_id) as '部署名', 3 count(*) as '部署の人数' 4from 5 ( 6 select 7 name, 8 division_name, 9 b.division_id 10 from 11 member as a 12 join 13 division as b 14 on a.division_id = b.division_id 15 ) as c 16group by 17 c.division_id 18;

なお、一応SELECT句に入れていない列でも以下のように行が特定できるのであればソート自体は可能です。

sql

1-- 指定していないmember_idでのソート 2 3select name from member order by member_id;

今回の問題は、group byとの兼ね合いかと思います。division_namegroup byした結果の各行はdivision_id で特定できなくなっています。devision_iddivision_nameも性質上ユニークなのかもしれませんが、それはSQLで推測されないので、エラーになってるのかと思います。

投稿2018/05/31 14:15

denzow

総合スコア640

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

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

michael-ilcsy

2018/05/31 14:31

回答ありがとうございます! 教えてもらったコードで思ったとおりに動きました。 >SELECT句に入れていない列でも以下のように行が特定できるのであればソート自体は可能です。 そうなんですね!selectしてないとダメだと思っていました。 まだサブクエリやjoinでのテーブルのイメージがついていないので、selectしていないdivision_idでgroup byしているのがよくわからないんですが、これは今回のidとnameが1対1対応しているからなのでしょうか?
denzow

2018/05/31 14:37

先程のSQLは**division_id**をSELECTにいれた上でgroup by していますよ。そしてそのSELECTに含めた**division_id**をもとに` (select divsion_name from division where division_id = c.division_id)`という部分でdivision_nameをさらに取り出しているだけですね。 つまり、 |division_id|count| |----|----| |1 | 2| |2| 2| |3|6| |4|2| という結果を一度出した上で、division_idをサブクエリでdivision_nameにしています。
michael-ilcsy

2018/05/31 14:57

考えてみましたが、やはりdivision_idがどこで現れたのかわかりません… 自分のイメージでは(select divsion_name from division where division_id = c.division_id)は いきなり部署名のn行1列の表が出来るイメージなので、何故これが元々はdivision_idで division_id|count の表が出来るのかがわからないです。 ちょっと自分でも結果のイメージ(どういう処理がどういう表を返してくるか)がごちゃごちゃしてて上手く説明できませんが…
papinianus

2018/05/31 15:33

横から失礼します - n行1列じゃなくて、1行1列です。n行1列からwhereでc.division_idでしぼっているから。 - c.division_id | count(*)の表でです(c.をちゃんと追わないと意味不明になると思います) 部署名じゃなくて、部署idを抽出するとしたら回答は select c.division_id as '部署ID', count(*) as '部署の人数' from ( select name, division_name, b.division_id from member as a join division as b on a.division_id = b.division_id ) as c group by c.division_id ; となりますよね。これの部署idを名前に変更する問い合わせをかけています。 もし部署名のところのselectがわかりにくいのであれば、↑をdivisionとjoinして名前を取る方法を考えてみたらいかがでしょうか(そうすると意味が理解できるかなと)
michael-ilcsy

2018/05/31 16:02

papinianusさん >もし部署名のところのselectがわかりにくいのであれば、↑をdivisionとjoinして名前を取る方法を考えてみたらいかがでしょうか(そうすると意味が理解できるかなと) 一応書いてみました select d.division_name,e.部署の人数 from division as d join ( select c.division_id as '部署ID', count(*) as '部署の人数' from ( select name, division_name, b.division_id from member as a join division as b on a.division_id = b.division_id ) as c group by c.division_id ) as e on d.division_id=e.部署ID ; が、やはり(select divsion_name from division where division_id = c.division_id)がc.division_idだったのかが意味不明です。 もう頭がこんがらがってわけがわからなくなってきました
papinianus

2018/06/01 00:52

理解できていると思えるSQLが書けているので、ちょっとした閃きなんですかね。 一応ということで書いておられるSQLをdを使わないで書くとこうなりますよね? select division_name,e.部署の人数 from division join ( select c.division_id as '部署ID', count(*) as '部署の人数' from ( select name, division_name, b.division_id from member as a join division as b on a.division_id = b.division_id ) as c group by c.division_id ) as e on division_id=e.部署ID ; こうすると、このSQLのいちばん外が (select divsion_name from division where division_id = c.division_id) とほぼ同じような構造をしているのが分かるのではないかと思います。 [select division_name from division ... 条件 division_id = [抽出テーブル].division_id] あるいは、同じテーブルだと思うからわかりにくいのでしょうか。 仮にdiv_managerテーブルというのがあって、それにdivision_idとmanager_nameがあると仮定します。 管理職とその管理職の部下の数を引いてくると考えると select (select manager_name from div_manager where div_manager.division_id = c.division_id) as '部署名', count(*) as '部署の人数' from ( select name, division_name, b.division_id from member as a join division as b on a.division_id = b.division_id ) as c group by c.division_id ; 逆に混乱を招くコメントになってすみません。 とりあえず理解しやすい別のかたちの回答がでたようですし、少し寝かせてみて時間をおいてふりかえると案外すんなり飲み込めるようにも思います
michael-ilcsy

2018/06/01 01:15

(select manager_name from div_manager where div_manager.division_id = c.division_id) でselectしているのはmanager_nameであってdivision_idは絞込みに使っているだけ(と思っている)なので、どこからdivision_idの列が生まれてる(そしてnameに変わっている)のかが分かりません。 仰るとおりこれ以上考えても進展しなさそうなので一旦時間をおいてみます。 長々と付き合っていただきありがとうございました!
guest

0

memberのdivision_idが文字列型なのに対してなぜdivisionのdivision_idは数値型なのでしょう?

サンプル

SQL

1create table member( 2member_id INT, 3name VARCHAR(10), 4division_id INT); 5 6insert into member values 7(1,'aaa',101), 8(2,'bbb',101), 9(3,'ccc',102), 10(4,'ddd',102), 11(5,'eee',102), 12(6,'fff',103), 13(7,'ggg',103), 14(8,'hhh',103), 15(9,'iii',104); 16 17create table division( 18division_id INT, 19division_name VARCHAR(10)); 20 21insert into division values 22(101,'営業部'), 23(102,'人事部'), 24(103,'システム部'), 25(104,'総務部');

検索

SQL

1select t1.division_name,t2.c from division as t1 2inner join (select division_id,count(*) as c from member group by division_id) as t2 on t1.division_id=t2.division_id 3order by t1.division_id 4

投稿2018/05/31 14:16

yambejp

総合スコア114572

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

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

michael-ilcsy

2018/05/31 14:38

回答ありがとうございます! 教えてもらったコードで思ったとおりに動きました。 >memberのdivision_idが文字列型なのに対してなぜdivisionのdivision_idは数値型なのでしょう? 問題を確認しましたがcharとintでした。おそらくミスですかね? 先にjoinすることばっかり頭にあって、memberだけで部署人数をカウントするということが思いつきませんでした、勉強になります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問