- ベストアンサー
テキストエリアに入力した複数行のデータをもとに、DBから呼び出したデータをPHP側でソート
PHP: 5.2.1 MySQL: 5.0.27 PHPとMySQLのバージョンは上記の通りです。 Smartyも利用しております。 (1) テキストエリアに以下のような情報を入力します。 ┏━━━━━━━━━━━┓ ┃ 5 ┃ 3 ┃ 1 ┃ 2 ┃ 4 ┗━━━━━━━━━━━┛ (2) 上記の情報をもとにデータベースに情報を取りに行きます。 (3) その結果、以下の情報が取得できます。 ID┃NAME ┃PRICE ━╋━━━╋━━━ 1 ┃メロン┃1000 2 ┃りんご┃100 3 ┃ぶどう┃300 4 ┃バナナ┃150 5 ┃みかん┃100 (4) このデータを、(1)でテキストエリアに入力した順番に並べ替えて表示する。 ┏━━━━━━━━━━┓ ┃5 みかん 100 ┃3 ぶどう 300 ┃1 メロン 1000 ┃2 りんご 100 ┃4 バナナ 150 ┗━━━━━━━━━━┛ という処理を行いたいのですが、(4)の部分が出来ません。 始めは1件1件問い合わせをかけて、1件ずつ表示すればと思ったのですが、 テキストエリアに入力する情報が1000件を超える場合があります。 速度に不安があるので、まとめて問い合わせする方法でやりたいのですが、 そうなると、どうしてもPHP側でソートさせる必要があります。 しかし、ソートさせるための基準となるものが 「テキストエリア内の情報の順番」なのです。 array_multisort関数なども試してみたのですが、 うまくいきませんでした。 データベースの書き換えを行わず、且つ、 1件ずつ問い合わせする方法もしない。といった場合、 上記を再現する事は可能でしょうか? お知恵をお貸し頂ければ幸いです。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
ORDER BY ID IN (5,3,1,2,4) DESC,FIELD(ID,5,3,1,2,4) とかMySQLでソートしてみては?
その他の回答 (3)
- little-m
- ベストアンサー率44% (45/102)
以下のようなロジックで出来るのではと思います。 ただし、(3)のデータベースから取得した情報のIDが、(4)のテキストエリアで指定されたIDの中に無かった場合どうするか、という問題があります。 【前提1】 (3)の結果を仮に $recs という配列に格納したとします。 $recs[0] --- array('id'=>1, 'name'=>'メロン', 'price'=>1000); $recs[1] --- array('id'=>2, 'name'=>'りんご', 'price'=>100); 【前提2】 (4)の結果を $sdats という配列に格納したとします。 $sdats = array(5, 3, 1, 2, 4,...) 【ロジック】 // 表示順の配列 $skeys を作ります $skeys = array(); $cnt = 0; foreach ($sdats as $id) { $skeys[$id] = $cnt; $cnt ++; } // データをソートします。 usort($recs, "cmp_recs"); // ソート用関数 function cmp_recs($a, $b) { global $skeys; // $skeys をグローバル変数で渡します $dnum = 99999; // $skeys に ID がない場合のダミー順番号 $aid = $a['id']; $bid = $b['id']; $anum = isset($skeys[$aid]) ? $skeys[$aid] : $dnum; $bnum = isset($skeys[$bid]) ? $skeys[$bid] : $dnum; return $anum < $bnum ? -1 : 1; }
お礼
ご回答頂きましてありがとうございます。 usort関数を利用する方法ですね! 色々調べて、まずその方法にたどり着いたのですが、 今回の作業が、未解析のクライアントのシステムで、且つ、複雑怪奇な構造でしたので、 いくら試してもエラー。エラー。エラー…。 私の勉強不足が一番の原因なのですが、(汗 今回は納期が迫っていましたので、とりあえずANo.1の方の方法で実装したいと思います。 また今回のような状況になったら、 教えて頂いたロジックを参考に組んでみようと思います。 非常に勉強になりました。 ありがとうございました。
- okweb-goo
- ベストアンサー率29% (283/952)
FORM入力から1000行ものデータを送り込むこと自体、設計に無理がありませんか?SQL文がものすごいことになりますよね。 まさかその1000行をキーボード入力しているとは思えませんが、まとめてファイルのアップロードではだめなんですか? 普通はそうしますし、そのほうがバグの追っかけも楽です。
お礼
ご回答頂きましてありがとうございます。 おっしゃる通りで、SQL文がものすごいことになっております。(汗 CSVファイルのアップロードも考えたのですが、 利用者側の事を考えるとフォームにせざるを得なかった次第です。 メンテナンスの事も考慮して、次回はファイルアップロード形式も検討したいと思います。 ありがとうございました。
- shimix
- ベストアンサー率54% (865/1590)
1000件にもなる可能性があるのなら、テンポラリテーブルにセッションID(もしくは適当なテンポラリ文字列),行No,入力した値を落としておいて、結合しないとselectのSQL文が大変なことになりませんか? そうしておけば、テンポラリの行No順で取り出せます。取り出し終わったらテンポラリからセッションIDが一致するレコードを削除すればよろしいかと(定期的にテンポラリはtruncateした方がいいかもしれませんが・・)。
お礼
ご回答頂きましてありがとうございます。 知識不足でその発想に至りませんでした。(汗 なるほど!そういう手もあるのですね! 今回の作業が、未解析のシステムでの作業でしたので、 データベース操作はSELECTだけがいいだろうと判断しておりました。 その為、PHP側でのソートにばかり気がいってしまい、 MySQLを利用してのソートの発想がありませんでした。 勉強になります! ありがとうございました。
お礼
ご回答頂きましてありがとうございます。 SQLでソート! 完全に頭から抜けていました(汗 今回はデータのやり取りの速度も求められましたが、 納期の方の速度が、それ以上に求められていたので、 簡単に実装できるこの形でいきたいと思います。 非常に助かりました。ありがとうございます。