以下のようなテーブル table1 があります。
*******************
table1
*******************
Name, Kyouka, Score, ID
*******************
山田, 国語, 92, 10001
鈴木, 国語, 71, 10002
田中, 国語, 89, 10003
山田, 数学, 65, 10004
鈴木, 数学, 69, 10005
杉田, 英語, 96, 10006
山田, 英語, 63, 10007
田中, 英語, 76, 10008
...
*******************
カラムIDはPRIMARYを指定しています。
カラムScoreはインデックスを作成しています。
このテーブルで、「IDと教科」を指定したときに、以下の2つのデータを得たいと思っています。
(1) IDに対応する名前と、その教科中の順位
(2) その教科のレコード数
具体例としては、例えば「ID=10001、教科=国語」を指定したときに、「山田、3人中1位」というような情報が得たいです。
(「ID=10001、教科=英語」のようなおかしな組み合わせは指定しないようになっています。)
(1) は、以下のようにして名前と順位を得る事が出来ました。
SELECT Name,
(SELECT COUNT(*) + 1 FROM table1 b WHERE b.Score > a.Score and Kyouka='国語') AS rank
FROM table1 a
WHERE ID='10001'
ORDER BY Score DESC;
(2)は、以下のようにして特定の教科のレコード数を得る事が出来ました。
SELECT COUNT(*) FROM table1 WHERE Kyouka='国語';
しかし、実際にはレコード数が大量にあり、頻繁にこの検索を実行する予定なので、負荷が心配です。
出来るだけサーバーの負荷を減らすために、1回のSELECT文の実行で(1)と(2)をどちらも実現できるような方法はないでしょうか。
また、このテーブルでインデックスを作成しているのはIDとScoreのみですが、より負荷を減らすにはKyoukaにもインデックスを作成した方が良いでしょうか。
何卒、よろしくお願いいたします。
No.3ベストアンサー
- 回答日時:
教科中の順位とその教科のレコード数を1回で取得するなら、下記の様にSELECT句内のサブクエリを一つ追加すれば良いだけです。
----------------------------------------
SELECT
Name,
Kyouka,
Score,
(SELECT COUNT(*) + 1 FROM table1 b WHERE b.Score > a.Score AND a.Kyouka = b.Kyouka) AS rank,
(SELECT COUNT(*) FROM table1 c WHERE a.Kyouka = c.Kyouka) AS count
FROM table1 a
WHERE ID = '10001'
ORDER BY Kyouka, Score DESC;
----------------------------------------
また、上記の様に教科をサブクエリ内の結合条件で絞り込んでやると、WHERE句の条件を変えるだけで色々な絞込みが可能です。
例) [国語の全データを取得] -------------
SELECT
Name,
Kyouka,
Score,
(SELECT COUNT(*) + 1 FROM table1 b WHERE b.Score > a.Score AND a.Kyouka = b.Kyouka) AS rank,
(SELECT COUNT(*) FROM table1 c WHERE a.Kyouka = c.Kyouka) AS count
FROM table1 a
WHERE Kyouka = '国語'
ORDER BY Kyouka, Score DESC;
----------------------------------------
性能が気になるようでしたら、下記の様にカウントはFROM句内のサブクエリで取得した方がよいかも知れません。
----------------------------------------
SELECT
Name,
Kyouka,
Score,
(SELECT COUNT(*) + 1 FROM table1 b WHERE b.Score > a.Score AND a.Kyouka = b.Kyouka) AS rank,
c.count
FROM table1 a INNER JOIN
(SELECT Kyouka, COUNT(*) AS count FROM table1 GROUP BY Kyouka) c USING(Kyouka)
ORDER BY Kyouka, Score DESC;
----------------------------------------
なお、他の方も指摘されている通り、Kyoukaカラムにもインデックスを張ったほうが良いと思います。
No.2
- 回答日時:
負荷を減らすという事なら、この場合SQLを1回にするよりも、
(2)の教科のレコード数は、ID別に毎回取得する必要は無さそうに思いますので、
その負荷が無駄になるという理由から、
(2)教科のレコード数は複数のIDに対して一回だけ取得し、
プログラムの変数等に格納しておくほうが効率的だと思います。
いずれにしてもKyoukaにインデックスを作成したほうがよいです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・あなたの人生で一番ピンチに陥った瞬間は?
- ・初めて見た映画を教えてください!
- ・今の日本に期待することはなんですか?
- ・【大喜利】【投稿~1/31】『寿司』がテーマの本のタイトル
- ・集中するためにやっていること
- ・テレビやラジオに出たことがある人、いますか?
- ・【お題】斜め上を行くスキー場にありがちなこと
- ・人生でいちばんスベッた瞬間
- ・コーピングについて教えてください
- ・あなたの「プチ贅沢」はなんですか?
- ・コンビニでおにぎりを買うときのスタメンはどの具?
- ・おすすめの美術館・博物館、教えてください!
- ・【お題】大変な警告
- ・【大喜利】【投稿~1/20】 追い込まれた犯人が咄嗟に言った一言とは?
- ・洋服何着持ってますか?
- ・みんなの【マイ・ベスト積読2024】を教えてください。
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・最強の防寒、あったか術を教えてください!
- ・【大喜利】【投稿~1/9】 忍者がやってるYouTubeが炎上してしまった理由
- ・歳とったな〜〜と思ったことは?
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
INSERT文でフィールドの1つだ...
-
SQLについて教えて下さい with(...
-
JOINで1つのテーブルに空白があ...
-
SQLでフィールドの順番を変更し...
-
DB2でのロック
-
SQL Server 2005 Express で CD...
-
SQLServerでの切り上げ処理
-
SQL server改行コード
-
count集計の結果が0の場合でも...
-
「重複を間引いた数」をcountし...
-
差し込み後、元データを変更し...
-
フィルターかけた後、重複を除...
-
外部参照してるキーを主キーに...
-
SQLで特定の項目の重複のみを排...
-
EXISTSを使ったDELETE文
-
エクセルで最後の文字だけ置き...
-
処理件数を非表示にしたい
-
SELECT 文 GROUP での1件目を...
-
1日に1人がこなせるプログラム...
-
SQL Date型の列から年月だけを...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
INSERT文でフィールドの1つだ...
-
SQLについて教えて下さい with(...
-
count集計の結果が0の場合でも...
-
SQLでフィールドの順番を変更し...
-
JOINで1つのテーブルに空白があ...
-
SQLServerでの切り上げ処理
-
'internal' のシステム メモリ...
-
自作関数の方がパフォーマンス...
-
SQL server改行コード
-
グループ毎の最大値を持つデー...
-
SQL Server 2005 Express で CD...
-
「重複を間引いた数」をcountし...
-
MySQLで複数のSELECT文を1文に...
-
DB2でのロック
-
Unionの結果全体をOrder By し...
-
mysqlのalter table中のロック...
-
md5で暗号化して別フィールドに...
-
SQLを作ったのですがうまくいき...
-
uniqueキーをupdateで+1するとE...
-
差し込み後、元データを変更し...
おすすめ情報