プロが教えるわが家の防犯対策術!

MySqlから以下の配列を出力し、各店舗ごとにseihin_A~seihin_Dが何番目に安いのかを算出したいと考えています。

$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;

この配列から、たとえばC社を選んだとき、

製品A(seihin_A) 2位
製品B(seihin_B) 1位
製品C(seihin_C) 除外
製品D(seihin_D) 3位

と各製品ごとの順位結果を出力するには、配列をどのように処理したらよいでしょうか。

ご教示よろしくお願いいたします。
(ちなみにCakePHPを使っています)

A 回答 (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>";
}
?>
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
簡単に思い通りの結果になりました。
ソース見せてもらうと納得できるのですが、自分にはまだ難しくて書けないですね。とても勉強になります。

お礼日時:2012/03/08 16:58

仮にテーブル定義が次のようだとし、


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)
);

格納されているデータが次のようだとしたら、
idnamecatseihinaseihinbseihincseihind
1Asya115002158040055000
2Bsya101858050054800
3Csya2160017000065000

次のようなクエリで、
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
1Asya 150022158014002550002
2Bsya 031858025001548003
3Csya 1600117000303650001

誰かの参考になれば。
会社数が増減し、製品種類も増減するなら、ちょっと面倒かも。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
CakePHPなのでバーチャルフィールドを使うことも検討したのですが、おっしゃる通り会社や製品名が増減したときに大変なんですよね。
今回私が考えているものは、項目の増減を前提としているのでSQLではデータを全て吐き出させるようにしました。出力する項目が増えてきたらリミットを設けてしのごうと思っています。

お礼日時:2012/03/08 16:58

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;
}
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
同じ値だった場合の順位付けは複雑になるので難しいですね。ご教示くださったソースを参考にさせていただきます。

お礼日時:2012/03/08 16:58

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