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

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

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

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

3回答

4151閲覧

mysqlのサブクエリに関して|複数のテーブルを使用し条件に合うレコードを抽出したい

DaikiYamada

総合スコア11

MySQL

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

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2015/11/23 13:36

サブクエリを勉強してます。

■やりたいこと
売上の平均以上を達成した社員の名前を抽出したい

■分からないこと(迷っていること)
//売上平均の算出
//"select avg(sale) from sales";
//売上の平均以上を達成したsalesテーブルのレコードを抽出
//select * from sales where sale > (select avg(sale) from sales);

上記まではできました。がsalesのmember_idをもとに売上平均以上の社員名をsql文で
どう書けば良いのかわかりません。
以下のようなsql文を考えましたが、そもそも書き方が間違ってますか?
select * from members where member_id = (select member_id from sales where sale > select avg(sale) from sales);

■前提条件

salesテーブル

1member_id, sale, month 21 , 75 , 4 32 , 200 , 5 43 , 15 , 6 54 , 700 , 5 65 , 672 , 4 76 , 56 , 8 87 , 231 , 9 98 , 459 , 8 109 , 8 , 7 1110 , 120 , 4 12売上合計:2,536 13売上平均:253.6

membersテーブル

1member_id, name 21 , Tanaka 32 , Sato 43 , Suzuki 54 , Tsuchiya 65 , Yamada 76 , Sasaki 87 , Harada 98 , Takahashi 109 , Nishida 1110 , Nakada

ageテーブル

1member_id, age 21 , 24 32 , 25 43 , 47 54 , 55 65 , 39 76 , 26 87 , 43 98 , 33 109 , 24 1110 , 20 12``` --> 13 14```php 15<?php 16 17require_once('functions.php'); 18 19$dbh = connectDb(); 20 21$sql = "select * from members where member_id = (select member_id from sales order by sale desc limit 1)"; 22$stmt = $dbh->prepare($sql); 23$stmt->execute(); 24$rows = $stmt->fetchAll(PDO::FETCH_ASSOC); 25//var_dump($rows); 26 27foreach ($rows as $row) { 28 echo "1.最大の売上を出した社員の名前:".$row['name']."<br>"; 29} 30//var_dump($row['name']); 31 32 33// 2.売上の平均以上を達成した社員の名前の算出方法 34// 35 36 37$sql = "select avg(sale) from sales"; 38$stmt = $dbh->prepare($sql); 39$stmt->execute(); 40$avg = $stmt->fetchAll(PDO::FETCH_ASSOC); 41var_dump($avg); 42 43 44echo "2.売上の平均以上を達成した社員の名前:"."<br>"; 45echo "1.30代以下の社員が達成した売上の合計:"."<br>";

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

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

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

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

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

guest

回答3

0

select * from members where member_id = (select member_id from sales where sale > select avg(sale) from sales);

このままだと動作しないですが、この方向で書き直すと多分次のようになると思います。

sql

1SELECT * 2FROM members m 3WHERE EXISTS ( 4 SELECT * 5 FROM sales s 6 WHERE m.member_id = s.member_id 7 AND sale > ( 8 SELECT avg(sale) 9 FROM sales 10 ) 11);

これでも動作するんじゃないかと思います。
しかしサブクエリをネストすると重いと聞きますので、アナライズは行った方が良いかも知れません。
※実質最下層のサブクエリは固定値の取得だけなので、existsが速いかjoinが速いかという話になりそうですが…。
私ならKiyoshiMotokiさんが書かれたコードのようにjoinを使うと思います。
コードの可読性もそちらのほうが良いですし、売り上げデータを付けたくなってもjoinのほうなら簡単に対応できます。

投稿2015/11/23 21:30

編集2015/11/23 21:35
hirohiro

総合スコア2068

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

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

0

以下で、いかがでしょうか?

sql

1SELECT DISTINCT m.member_id, m.name 2FROM sales AS s INNER JOIN members AS m ON s.member_id = m.member_id 3WHERE s.sale > (SELECT AVG(sale) FROM sales);

実行結果

sql

1mysql> SELECT DISTINCT m.member_id, m.name 2 -> FROM sales AS s INNER JOIN members AS m ON s.member_id = m.member_id 3 -> WHERE s.sale > (SELECT AVG(sale) FROM sales); 4+-----------+-----------+ 5| member_id | name | 6+-----------+-----------+ 7| 4 | Tsuchiya | 8| 5 | Yamada | 9| 8 | Takahashi | 10+-----------+-----------+ 113 rows in set (0.00 sec)

投稿2015/11/23 16:12

KiyoshiMotoki

総合スコア4791

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

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

0

http://www.atmarkit.co.jp/ait/articles/1208/06/news118.html
サブクエリで複数行を返すような時はINを使います。

ただ、MySQLではサブクエリ+INを使った場合にパフォーマンスが出ないケースがあるので
https://www.google.co.jp/search?q=MySQL+%E3%82%B5%E3%83%96%E3%82%AF%E3%82%A8%E3%83%AA+in&oq=MySQL+%E3%82%B5%E3%83%96%E3%82%AF%E3%82%A8%E3%83%AA+in&aqs=chrome..69i57j0l5.3874j0j4&sourceid=chrome&es_sm=93&ie=UTF-8#
無理にサブクエリで実行するよりは
結果をPHPで整形してから別のクエリにするか、JOINして取得するのが無難そうです。

投稿2015/11/23 14:44

tanat

総合スコア18709

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問