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

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

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

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

SQL

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

PHP

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

Q&A

解決済

1回答

921閲覧

[MySQL、PHP]異なるカラムを比較して上位x件を取得したい

Discord

総合スコア51

MySQL

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

SQL

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

PHP

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

0グッド

0クリップ

投稿2021/09/30 05:11

編集2021/09/30 05:18

下記のようなDBテーブルの構成があります。

|id|name|kokugo|sugaku|eigo|
:--|:--:|--:|
|1|佐藤|70|80|85|
|2|鈴木|60|90|80|
|3|高橋|80|55|95|
|4|川島|85|95|70|
|5|若林|60|75|90|

この場合、個人個人の点数で、良い点数の科目上位2つを取りたいです。
例えば佐藤さんなら、eigoとsugakuの順で2つだけselect、鈴木さんならsugaku、eigoの順で2つだけselectみたいな感じです。

SQLだとどうやって良いのかまったくわからずでして。
ちなみに取得データを配列に入れるのですが、その処理はPHPで行うので、一旦取得してきてPHPで並び替えるでも良いのですが、どっちにしろアルゴリズムが思いつかずでして。。

取得後のデータのイメージとしては、下記のような感じです。
$hoge['佐藤'] = ['eigo' => 85, 'sugaku' => 80];
$hoge['鈴木'] = ['sugaku' => 90, 'eigo' => 80];

ちなみに同じ点数だった場合は、今のカラムの並び順を優先としたいです。
(kokugo,sugaku,eigo)

3つとも同じ場合は、kokugo,sugakuの順で2つ取得したいです。

ご教示いただけると幸いです。

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

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

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

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

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

yambejp

2021/09/30 05:14 編集

TOP2教科が同じ点数だった場合表示上どちらが先になるのでしょうか? 3教科すべてが同じ点数だった場合どうするのでしょうか?
Discord

2021/09/30 05:18 編集

コメントありがとうございます! 同じ点数だった場合は、今のカラムの並び順を優先にしたいです。 (kokugo,sugaku,eigo) 3つとも同じ場合は、kokugo,sugakuの順で2つ取得したいです。 質問も修正しておきます。
yambejp

2021/09/30 05:20

追加で申し訳ないですがmysqlのバージョンを明記ください
m.ts10806

2021/09/30 05:21

PHPはオブジェクト操作になるし二度手間になります。 SQLで使いたい形式で取るほうが簡単です。
Discord

2021/09/30 05:23

mysqlのバージョンが5.7です!
guest

回答1

0

ベストアンサー

まずカラム同士の比較をするならデータの持ち方がおかしいです。
むりやり処理をするなら一旦ビューをつくるとよいでしょう

SQL

1/* 元データ */ 2create table tbl(ID int primary key,name varchar(10),kokugo int,sugaku int,eigo int); 3insert into tbl values 4(1,'佐藤',70,80,85), 5(2,'鈴木',60,90,80), 6(3,'高橋',80,55,95), 7(4,'川島',85,95,70), 8(5,'若林',60,75,90), 9(6,'坂本',90,90,90); 10 11/*ビューの作成*/ 12create view v as 13select ID,kyoka,point,(select count(*)+1 from( 14select *,case kyoka when 'kokugo' then 1 when 'sugaku' then 2 else 3 end as sort 15from( 16select ID,'kokugo' as kyoka ,kokugo as point from tbl 17union all select ID,'sugaku',sugaku from tbl 18union all select ID,'eigo',eigo from tbl 19) as t3 )as t4 where t2.ID=t4.ID and (t2.point<t4.point or t2.point=t4.point and t2.sort>t4.sort)) as rank 20 from( 21select *,case kyoka when 'kokugo' then 1 when 'sugaku' then 2 else 3 end as sort 22from( 23select ID,'kokugo' as kyoka ,kokugo as point from tbl 24union all select ID,'sugaku',sugaku from tbl 25union all select ID,'eigo',eigo from tbl 26) as t1 )as t2; 27 28select * from v; 29

ここから上位2個をとりだしますが、順位順にとりだすならjsonデータなどにしないといけません

SQL

1select ID,concat('[',group_concat(concat('{"',kyoka,'"',':',point,',"rank":',rank,'}') order by rank separator ',' ),']') 2as json 3from v 4where rank<=2 5group by ID

結果:

IDJSON
1[{"eigo":85,"rank":1},{"sugaku":80,"rank":2}]
2[{"sugaku":90,"rank":1},{"eigo":80,"rank":2}]
3[{"eigo":95,"rank":1},{"kokugo":80,"rank":2}]
4[{"sugaku":95,"rank":1},{"kokugo":85,"rank":2}]
5[{"eigo":90,"rank":1},{"sugaku":75,"rank":2}]
6[{"kokugo":90,"rank":1},{"sugaku":90,"rank":2}]

投稿2021/09/30 06:30

yambejp

総合スコア116720

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

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

Discord

2021/09/30 06:39

ありがとうございます! たしかにビューを作成すればいけそうですね。 ちなみにこういった場合、どういうデータの持たせ方が良いのでしょうか。
yambejp

2021/09/30 06:42 編集

> どういうデータの持たせ方が良い ビューで表示されるような持ち方です (ただしrankは都度計算することになりますが)
Discord

2021/09/30 06:51

なるほど、ありがとうございます! そのあたりも含めて再考してみたいと思います。 非常に助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問