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

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

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

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

Q&A

解決済

2回答

3957閲覧

mysqlのサブクエリを同じsql文内で複数回使用したい

joeast

総合スコア26

MySQL

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

0グッド

0クリップ

投稿2018/06/14 03:24

編集2018/06/14 05:32

sql

1select (select count(*)+1 from (select usf_sid, count(*) as ct from usfavo group by usf_sid) as t1 where t1.ct > t2.ct ) as rank from (select usf_sid, count(*) as ct from usfavo group by usf_sid) as t2 where usf_sid=1

現在このようなクエリを実行しております。
内容は、usfavoテーブルをusf_sidでグループ化しその数をカウントします。
その中で usf_sid=1 のものが上位何番目にあたるかを一度のクエリで取得しています。
上記のクエリは正常に動作しますが、問題なのは、

(select usf_sid, count(*) as ct from usfavo group by usf_sid)

このサブクエリですが、select句とfrom句に同じものを2度記述しています。
これをスマートに一回のサブクエリの記述にまとめたいです。

with句は試してみたのですが、mysqlのバージョンが5.7な為か、使用できませんでした。
その他の方法も探してみたのですが、明確な答えが出せなかった為質問させていただきました。
お分かりの方がおられましたらご教示いただけないでしょうか。
よろしくお願いいたします。

sql

1select count(*)+1 2from (select usf_sid, count(*) as ct1 from usfavo group by usf_sid) t1 3where ct1 > (select count(*) from usfavo where usf_sid=1)

こちらのコードで解決いたしました。
ご回答いただいた皆様、ありがとうございます。
ご指摘いただいた点など参考にさせていただき、勉強してきます。

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

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

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

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

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

yambejp

2018/06/14 03:38

create tableとinsert intoで具体的なサンプルデータと、ほしい結果を例示できませんか?
Orlofsky

2018/06/14 03:40

CREATE TABLE文や数件で良いから現状のデータのINSERT文も載せると適切なコメントが付き易いです。コードは 対応しているMarkdownの機能 https://teratail.com/help#about-markdown の[コードを入力]を使いましょう。
joeast

2018/06/14 03:46

ご指摘ありがとうございます、コードの記述について更新しました
joeast

2018/06/14 03:50 編集

ご指摘ありがとうございます、こちらのmysqlクエリで求める結果は得られている状態です。 今回質問させていただいたのは、 「select句とfrom句に同じサブクエリを記述している部分を、一回の記述へまとめられないか」 という部分になります。
yambejp

2018/06/14 03:57

いや、そうじゃなくて、サンプルデータがないと検証ができないので回答がブレるということです
joeast

2018/06/14 04:02

そうなのですね、ご指摘ありがとうございます、承知いたしました。 データを用意します。
guest

回答2

0

ベストアンサー

どうしても一度はusf_sid毎の件数を取得する必要があるので厳しいです。
MYSQLにrank()があれば、withが使えなくても大丈夫なんですけどね。
usf_sidを限定して取得を前提であれば以下のような記述でも可能です。
但し、性能的には検証できませんので、悪しからず。

SQL

1select count(*)+1 2from (select usf_sid, count(*) as ct1 from usfavo group by usf_sid) t1 3where ct1 > (select count(*) from usfavo where usf_sid=1)

#データ

SQL

1CREATE TABLE usfavo 2 (`usf_sid` int, `seq` int) 3; 4 5INSERT INTO usfavo 6 (`usf_sid`, `seq`) 7VALUES 8 (1, 1), 9 (1, 2), 10 (1, 3), 11 (2, 1), 12 (2, 2), 13 (2, 3), 14 (3, 1), 15 (3, 2), 16 (4, 1), 17 (4, 2), 18 (4, 3), 19 (4, 4) 20;

投稿2018/06/14 04:24

sazi

総合スコア25173

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

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

joeast

2018/06/14 05:28

saziさんからいただいたコードで正常に動作いたしました。 またサブクエリの重複もなくスマートに記述できており、 こちらのコードを参考にさせていただこうと思います。 ありがとうございました。
sazi

2018/06/14 05:47

質問のSQLと動作の違う点がありました。 存在しないusf_sidを指定された場合に値を返してしまう点です。 ※yambejpさんも同様。 その場合にも対応すると結局別な部分で冗長となります。
joeast

2018/06/14 06:06

ありがとうございます、承知いたしました。 現在のロジックでは存在しないusf_sidを指定される場合はまずありませんので、 こちらで運用可能かと考えております。 ご教示ありがとうございます。
guest

0

saziさんのデータをそのまま使うとすると、こうでもいいかもしれません

SQL

1select count(*)+1 from( 2select 1 from usfavo group by usf_sid 3having count(*)>(select count(*) from usfavo where usf_sid=1) 4) as sub

ただしやや効率がわるいかも

投稿2018/06/14 05:13

yambejp

総合スコア114784

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

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

yambejp

2018/06/14 05:17

ま、実際のところ「構文を見やすくしたい」ということならviewを使うのがラクなんですけどね
joeast

2018/06/14 05:26

viewについては知識不足でした。 ありがとうございます、調べてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問