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

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

解決済

5回答

17382閲覧

別テーブルのカウント数を条件にしてselectしたい

macharu

総合スコア24

MySQL

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

SQL

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

0グッド

0クリップ

投稿2017/11/09 02:10

簡易的な受発注システムのSQL文について質問です。

下記のような2つのテーブルが存在するとします。
ordersテーブルのuser_idにはusersテーブルのidが紐付いており、ユーザーの注文情報が追加されていく形になります。

この中でusersテーブルの中から、
「そのidとuser_idが紐付いたordersレコードのhoge_flgカラムがtrueであるレコード」の数が「1以上」となるユーザーをselectしたいです。

このテーブルであればIDが101、103、104のユーザーがselectされるようになるかと思います。

どういったSQL文であればselectできるようになりますでしょうか?
ヒントだけでも教えていただけると助かります。

###注文情報(orders)
|id|user_id|items|hoge_flg|
|:--:|:--:|:--:|
|1|101|items|true|
|2|102|items|false|
|3|102|items|false|
|4|101|items|false|
|5|103|items|true|
|6|101|items|false|
|7|104|items|true|
|8|103|items|false|

###ユーザー情報(users)

idname
101suzuki
102tanaka
103sato
104saito

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

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

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

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

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

guest

回答5

0

こうですかね。

SQL

1SELECT users.* FROM users WHERE users.id IN ( 2 SELECT user_id FROM orders WHERE hoge_flg = 'true' GROUP BY user_id HAVING COUNT(*) >= 1 3 );

サブクエリでhoge_flgがtrueのものに絞り込み、user_id単位でカウントして1件以上存在するuser_idだけを抽出して、それをusersのidとIN句で比較します。正直1以上という判定であればGROUP BYやHAVING COUNTなんてしなくてもhoge_flgがtrueなものを探すだけでいいんですが、今後1より大きい値で探したいときの為にちゃんとカウントを取って判定しました。

投稿2017/11/09 02:40

編集2017/11/09 02:42
masaya_ohashi

総合スコア9206

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

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

退会済みユーザー

退会済みユーザー

2017/11/09 03:07

カウントしてるところ悪いが一以上ならカウント不要なきが(笑)
guest

0

mysqlの場合、多少方言をつかったほうがさらっとかけますね

SQL

1select * from user where id in( 2select user_id from orders group by user_id having sum(hoge_flg=true)>0 3)

なおhoge_flgのようなフラグはtiny_intでfalse=0、true=1のような管理のほうが汎用性が高くなります

投稿2017/11/09 03:04

yambejp

総合スコア114585

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

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

0

こんにちは。

「1以上」=「1つでもあれば」ということですと、以下のSQLでいかがでしょうか。
(列hoge_flgの型はbooleanと仮定しています)

select distinct a.name from users a inner join orders b on b.userid=a.id where b.hoge_flg=true;

初回答で緊張しています。はずしていたらごめんなさい(^^;

投稿2017/11/09 02:39

dotnet

総合スコア25

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

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

0

いろいろな書き方があると思います。
INを使う方法がでていますが、INを使う方法は相関サブクエリになり遅くなる場合が多いらしいです。

EXISTSを使う方法もあり、こちらの方が早い場合が多いそうです。(user_id にインデックスが設定してあると特に)

SQL

1select a.name from users a 2where exists (select 1 from orders b where b.hoge_flg=true and b.user_id=a.id);

ただ、どちらにしても相関サブクエリに変わりはないので遅いらしい。
INNER JOINに置き換えることができるならそれが最速らしいです。

INNER JOINの方法は、dotnetさんの回答もありますが、下記のように先に絞ってからjoinした方が早そうです。

SQL

1select a.name from users a inner join 2(select distinct user_id from orders where hoge_flg=true) b on b.user_id=a.id;

参考URL
EXISTSとSQLの高速化について - 猫好きモバイルアプリケーション開発者記録

追記

相関サブクエリは遅いということは昔からよく言われてきたことですが、MySQLも日々進化しているはずなので、ちょっと調べてみました。下記によると5.6以降なら、オプティマイザによりjoin操作に書き換えて実行されるので、そんなに遅くならないらしいです。

MySQL のサブクエリって、ほんとに遅いの? | Developers.IO

投稿2017/11/09 05:41

編集2017/11/09 06:00
hatena19

総合スコア33620

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

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

suzukis

2017/11/09 06:07

INで相関サブクエリを使っている回答は今のところありませんが。
hatena19

2017/11/09 06:52

よく見たらそうでした。早とちりですみません。
dotnet

2017/11/09 07:40

勉強になりました。ありがとうございます!
guest

0

ベストアンサー

SELECT * FROM users WHERE id IN (SELECT DISTINCT user_id FROM orders WHERE hoge_flg = true);

DISTINCTつけてもつけなくてもは結果はかわらないですが、データの状況によっては性能に差が出るかもしれません。

投稿2017/11/09 02:21

suzukis

総合スコア1449

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

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

macharu

2017/11/09 10:09

ありがとうございます!こちらのSQLで対応できました!最初に解答いただいたということでベストアンサーとさせて頂きます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問