プロが教える店舗&オフィスのセキュリティ対策術

PHPとMy SQLを使って簡易なデーターベースを作っています。
そのなかで任意の順で表を並べ変えたいと思っています。

例えば、table1のt_idに3,6,11,2,4と番号が入っており、table2からtune_idを3,6,11,2,4 の順で並べたいと思っています。

現在は2,3,4,6,11の順でtable2が表示されているので、ORDER BYで指定したいのですが、指定の仕方がよく分かりません。解決方法を教えて頂けますと幸いです。

〇table1
t_id
3,6,11,2,4
11,1,5
4,15,2


〇table2
tune_id  title    comp
1     てすと1 あいう1
2     てすと2  あいう2   
3     てすと3  あいう3


<?php
$tid = $result['t_id'];

/*何も指定しないとtune_idで昇順で並ぶ*/
/* $stmt2 = $pdo->prepare("SELECT * FROM pet_tune WHERE tune_id in ('$tid')");*/
/*これを並び替えたい↓↓↓*/

/*任意の順に並べたい*/
$stmt2 = $pdo->prepare("SELECT * FROM table2 WHERE tune_id in ('$tid') ORDER BY CASE tune_id WHEN ('$tid') THEN 1");

$stmt2->execute();
$i = 1;

while( $result2 = $stmt2->fetch( PDO::FETCH_ASSOC ) ){
echo "\t<tr><td>$i</td>\n";
echo "\t\t<td>{$result2['title']}</td>\n";
echo "\t\t<td>{$result2['comp']}</td>\n";
echo "\t</tr>\n";
$i++;
}

?>

何かその他必要な情報がありましたら追記いたしますのでご指摘ください。
どうぞよろしくお願いいたします。

A 回答 (2件)

もちろん正規化をするのが上策ではありますが、


カンマ区切り文字列のままでも、問題なく文字列関数で処理できます。

案1)
order by FIND_IN_SET(tune_id, '3,6,11,2,4')

案2)
order by INSTR(
concat(',' , '3,6,11,2,4' , ',')
, concat(',' , tune_id , ',')
)

参考)
https://dev.mysql.com/doc/refman/8.0/ja/string-f …
https://dev.mysql.com/doc/refman/8.0/ja/string-f …
    • good
    • 0
この回答へのお礼

す、凄い、、、、
あっさりでできました。
DBの正規化というのをもう少ししっかりできたらと思いつつ、目先の変更が少なくできたこちらをやはり採用しようと思います。。。

教えて頂きありがとうございます。

お礼日時:2023/08/31 11:32

まず確認。


> 〇table1
> t_id
> 3,6,11,2,4

t_id は文字列型で「3,6,11,2,4」という文字列が入っている
という意味でいいですか?

○方針1: データベース側で処理する。
データーベースの基本である「正規化」を考えると、table1のデザイン自体に問題があります。

table1a
行番号 順位 tune_id
1   1 3
1   2 6
1   3 11
...
とすれば、 table2aとtable1aをtune_id でjoinし、「順位」で並び換えることができます。

どうしても現在のtable1を使いたいのなら、そこからtabl1a(あるいは同等の一時テーブル、テーブル変数等)に変換するプロシージャやビューを用意するとか。

○方針2: プログラム側で処理する
一旦全ての結果を配列等の保存し、そこからtune_id = 3,6,11,2,4 の順に読み出す。
PHPなら、 配列に保存するときの添字としてtune_idを使えば、呼び出しも楽になる。
    • good
    • 0
この回答へのお礼

早速ありがとうございます。

今回もともとHTMLで作っていたページをページが増えてきたので
勉強がてらPHP+MySQLの仕組みに変更しようとしています。
(ディスコグラフィーを作っています。それぞれのアルバムに重複する曲があるので曲をtable2に納め、table1から曲のtune_idを指定し曲順に並べようとしています)

DBの構成も何度か変更しているので折角?なので方針1で出来たらと思い改変を始めてみました。(t_id は文字列型です。今も残しています)

>○方針1: データベース側で処理する。
table1aというのはtable1とは別にもう一つtableを作るということでしょうか。どのように構成したらよいか分からず、ひとまずtable1を以下のように変更してみました。

〇table1(アルバムを一件ずつ格納、t_id_〇は曲ID、t_order_〇は曲順、idはアルバムid)
id t_order_1 t_id_1 t_order_2 t_id_2 t_order_3 t_id_3
1 1     4 2 13 3 2
2 1     1 2 4 3 5


〇table2(曲を一曲ずつ格納)
tune_id  title    comp
1     てすと1  あいう1
2     てすと2  あいう2   
3     てすと3  あいう3

この構成でそれぞれのt_id_〇をJOINすることはできますか。
DBの構成自体がおかしければアドバイス頂けますと幸いです。

$stmt = $pdo->prepare("SELECT * FROM table1 WHERE id='$id' INNER JOIN table2 ON table1.t_id_1= table2.tune_id");

よろしくお願いいたします。

お礼日時:2023/08/29 10:35

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

関連するカテゴリからQ&Aを探す


このQ&Aを見た人がよく見るQ&A