order byでハマったこと -order by、group byの処理順序-
環境
- MySQL
- PHP5
- CakePHP1.3
やりたいこと
最新巻(no)、設定ID(config_id)、発売日(salesdate)があるテーブルがあるとします。
テーブル構成/データ(例)
id | no | config_id | salesdate |
1 | 1 | 1 | 2011-11-12 |
2 | 2 | 1 | 2012-02-10 |
3 | 1 | 2 | 2012-01-04 |
4 | 1 | 3 | 2011-08-04 |
5 | 2 | 3 | 2011-12-03 |
このデータをconfig_idでグルーピングして、そのconfig_idの最新巻がいくつか知りたい。
つまり求める形は以下。
id | no | config_id | salesdate |
2 | 2 | 1 | 2012-02-10 |
3 | 1 | 2 | 2012-01-04 |
5 | 2 | 3 | 2011-12-03 |
やったこと&問題発生
CakePHPのmodelに以下を追加して最新巻のデータを取得しようとします。
public function getLatestNo() { $fields = array('config_id', 'no', 'salesdate'); $group = array('config_id'); $order = array('max_no desc'); $params = array('fields' => $fields, 'order' => $order, 'group' => $group,); $data = $this->find('all',$params); return $data; }
しかし、上記の場合だと、戻ってくるデータは以下の形。
[0] => Array([book] => Array ( [config_id] => 1 [no] => 1 [salesdate] => 2011-11-12 ) ) [1] => Array([book] => Array ( [config_id] => 2 [no] => 1 [salesdate] => 2012-01-04 ) ) [1] => Array([book] => Array ( [config_id] => 3 [no] => 1 [salesdate] => 2011-08-04 ) ) )
この原因は、order byよりgroup byが先に処理されるから。
※最初、気がつくのに時間がかかってしまった・・。 猛省。
解決策
そこで、以下のような形に変えます。
public function getLatestNo() { $fields = array('config_id', 'max(salesdate) as max_salesdate', 'max(no) as max_no'); $group = array('config_id'); $order = array('max_no desc'); $params = array('fields' => $fields, 'order' => $order, 'group' => $group,); $data = $this->find('all',$params); return $data; }
上記にすると以下のような形で帰って来ます。
[0] => Array([book] => Array ( [config_id] => 1 ) [0] => Array ( [max_salesdate] => 2012-02-10 [max_no] => 2 ) ) [1] => Array([book] => Array ( [config_id] => 2 ) [0] => Array ( [max_salesdate] => 2012-01-04 [max_no] => 1 ) ) [1] => Array([book] => Array ( [config_id] => 3 ) [0] => Array ( [max_salesdate] => 2011-12-03 [max_no] => 2 ) ) )
一応、最新巻で戻ってきていますが、これだと非常に使いづらい形です。
そこで、CakePHPのSet::combineを使います。
以下のように書きかえます。
public function getLatestNo() { $fields = array('config_id', 'max(salesdate) as max_salesdate', 'max(no) as max_no'); $group = array('config_id'); $order = array('max_no desc'); $params = array('fields' => $fields, 'order' => $order, 'group' => $group,); $data = $this->find('all',$params); $data = Set::combine($data, '{n}.book.config_id', '{n}.0'); return $data; }
上記のように、Set::combineを使うことによって以下のようにデータが返って来ます。
Array ( [1] => Array ( [max_salesdate] => 2012-02-10 [max_no] => 2 ) [2] => Array ( [max_salesdate] => 2012-01-04 [max_no] => 1 ) [3] => Array ( [max_salesdate] => 2011-12-03 [max_no] => 3 ) )
これで、なんとか使える形になりました。
参考サイト
広告
関連記事
-
iPhoneアプリ開発 -端末がネットワークにつながっているかどうか知りたい-
* やりたいこと アプリがネットに繋がっていなければアラートボックスを表示させたい。 ネットに繋
-
Jenkins + DeployGate(2) -DeployGateにアプリをアップ!-
DeployGateを使ってますか? 継続的にDeployってますか? TestFlightの
-
iPhoneアプリ開発 -UIScrollViewで画像を拡大・縮小-
* やりたいこと UIScrollViewでピンチアウト・インして上に乗っている画像を拡大・縮小した
-
iPhoneアプリ開発 芳名帳アプリ作成(2) -記帳画面作成-
* 今までの流れ - * 画面構成 今回の芳名帳アプリは以下の画面で構成しています。 -
-
iPhoneアプリ開発 -mixiSDKを使ってmixi連携をしてみる(2)-
* 前回 は、「ユーザーにAPI利用のための認可」をおこなってもらうところまでやりました。 本エン
-
研究室での進捗報告の方法について、ふと思ったこと
* 以下に加筆・修正して移動しました。
-
iPhoneアプリ開発 −2本指で画像を移動させる−
* やりたいこと 表示させている画像(UIImageView)を2本指で移動させたい。 ※1本指は別
-
jQuery Mobile1.2のCollapsible Listsを試してみた -画像のカスタマイズについて-
8月1日にjQuery Mobile1.2 Alphaが出ました。 まだAlphaなので自
-
複数アカウントでgithubを使う
1つの端末で複数のアカウントを使いたくなったので、その方法を整理してみた。 流れとしては以下のとおり
-
Objective-cで悩んでいたこと −アクセサのことについて−
* 疑問 以前書いたiPhoneアプリを開発していて(Objective-Cを触っていて)疑問に思