- ベストアンサー
配列から順位を算出する方法とは?
- MySqlから配列を取得し、各店舗ごとに製品の順位を算出したいです。
- 製品ごとに安い順に並び替え、順位を付ける方法を教えてください。
- CakePHPを使用しています。ご教示いただければ幸いです。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
おなじ価格があった場合順位をどうしたいかにもよりますね 命題の通りやる場合は、製品ごとにソートしてみれば ざっくりとした順位付けができそうですが・・・ たとえばこんな感じ? <?PHP $arr[0]["kihon"]["shop_name"] = "A社"; $arr[0]["kihon"]["shop_category"] = 1; $arr[0]["kakaku"]["seihin_A"] = 1500; $arr[0]["kakaku"]["seihin_B"] = 21580; $arr[0]["kakaku"]["seihin_C"] = 400; $arr[0]["kakaku"]["seihin_D"] = 55000; $arr[1]["kihon"]["shop_name"] = "B社"; $arr[1]["kihon"]["shop_category"] = 1; $arr[1]["kakaku"]["seihin_A"] = 0; $arr[1]["kakaku"]["seihin_B"] = 18580; $arr[1]["kakaku"]["seihin_C"] = 500; $arr[1]["kakaku"]["seihin_D"] = 54800; $arr[2]["kihon"]["shop_name"] = "C社"; $arr[2]["kihon"]["shop_category"] = 2; $arr[2]["kakaku"]["seihin_A"] = 1600; $arr[2]["kakaku"]["seihin_B"] = 17000; $arr[2]["kakaku"]["seihin_C"] = 0; $arr[2]["kakaku"]["seihin_D"] = 65000; $temp_array=array(); foreach($arr as $array){ foreach($array["kakaku"] as $key => $val){ if($array["kakaku"][$key] !=0){ $temp_array[$key][]=array("kakaku"=>$val,"shop_name"=>$array["kihon"]["shop_name"]); } } } foreach(array_keys($temp_array) as $key){ usort($temp_array[$key],"mysort"); } $rank=array(); foreach($temp_array as $key1=>$array1){ foreach($array1 as $key2=>$array2){ $rank[$array2["shop_name"]][$key1]=$key2+1; } } function mysort($a,$b){ if($a["kakaku"]==$b["kakaku"]) return 0; return $a["kakaku"]>$b["kakaku"]; } $str="C社"; foreach($rank[$str] as $product=>$rank){ print $product.":".$rank."<br>"; } ?>
その他の回答 (2)
- honoka-cha
- ベストアンサー率54% (40/73)
仮にテーブル定義が次のようだとし、 CREATE TABLE shop ( id int NOT NULL auto_increment, name varchar(10), cat int, seihina int, seihinb int, seihinc int, seihind int, PRIMARY KEY (id) ); 格納されているデータが次のようだとしたら、 id name cat seihina seihinb seihinc seihind 1 Asya 1 1500 21580 400 55000 2 Bsya 1 0 18580 500 54800 3 Csya 2 1600 17000 0 65000 次のようなクエリで、 SELECT s1.id, s1.name, s1.seihina, (SELECT count( s2.seihina ) FROM shop s2 WHERE s2.seihina > 0 and s2.seihina < s1.seihina) +1 juna, s1.seihinb, (SELECT count( s2.seihinb ) FROM shop s2 WHERE s2.seihinb > 0 and s2.seihinb < s1.seihinb) +1 junb, s1.seihinc, (SELECT count( s2.seihinc ) FROM shop s2 WHERE s2.seihinc > 0 and s2.seihinc < s1.seihinc) +1 junc, s1.seihind, (SELECT count( s2.seihind ) FROM shop s2 WHERE s2.seihind > 0 and s2.seihind < s1.seihind) +1 jund FROM shop s1 次のような結果が出ます。 id name seihina juna seihinb junb seihinc junc seihind jund 1 Asya 1500 2 21580 1 400 2 55000 2 2 Bsya 0 3 18580 2 500 1 54800 3 3 Csya 1600 1 17000 3 0 3 65000 1 誰かの参考になれば。 会社数が増減し、製品種類も増減するなら、ちょっと面倒かも。
お礼
ご回答ありがとうございます。 CakePHPなのでバーチャルフィールドを使うことも検討したのですが、おっしゃる通り会社や製品名が増減したときに大変なんですよね。 今回私が考えているものは、項目の増減を前提としているのでSQLではデータを全て吐き出させるようにしました。出力する項目が増えてきたらリミットを設けてしのごうと思っています。
- shimix
- ベストアンサー率54% (865/1590)
usortを使うといいのではないでしょうか? http://jp.php.net/manual/ja/function.usort.php とりあえず同額だったら同順位にするという仕様で書いて見ました。叩き台くらいにはなると思います。 (e.g.) <?php $arr = array(); $arr[] = array('kihon'=>array('shop_name'=>'A社', 'shop_category'=>1), 'kakaku'=>array('seihin_A'=>1500, 'seihin_B'=>21580, 'seihin_C'=>400, 'seihin_D'=>55000)); $arr[] = array('kihon'=>array('shop_name'=>'B社', 'shop_category'=>1), 'kakaku'=>array('seihin_A'=>0, 'seihin_B'=>18580, 'seihin_C'=>500, 'seihin_D'=>54800)); $arr[] = array('kihon'=>array('shop_name'=>'C社', 'shop_category'=>2), 'kakaku'=>array('seihin_A'=>1600, 'seihin_B'=>17000, 'seihin_C'=>0, 'seihin_D'=>65000)); $arr[] = array('kihon'=>array('shop_name'=>'D社', 'shop_category'=>1), 'kakaku'=>array('seihin_A'=>1500, 'seihin_B'=>21580, 'seihin_C'=>400, 'seihin_D'=>55000)); usort($arr, 'sort_seihin_a') or die('sort abort'); $cnt = 0; foreach ($arr as $item) { $cnt++; if ((!isset($sv))or($item['kakaku']['seihin_A'] !== $sv)) { $no = $cnt; } print $no . ':' . $item['kihon']['shop_name'] . ':' . $item['kakaku']['seihin_A'] . '<br />'; $sv = $item['kakaku']['seihin_A']; } function sort_seihin_a($ar1, $ar2) { if ($ar1['kakaku']['seihin_A'] == $ar2['kakaku']['seihin_A']) { return 0; } return ($ar1['kakaku']['seihin_A'] < $ar2['kakaku']['seihin_A']) ? -1 : 1; }
お礼
ご回答ありがとうございます。 同じ値だった場合の順位付けは複雑になるので難しいですね。ご教示くださったソースを参考にさせていただきます。
お礼
ご回答ありがとうございます。 簡単に思い通りの結果になりました。 ソース見せてもらうと納得できるのですが、自分にはまだ難しくて書けないですね。とても勉強になります。