order byでハマったこと -order by、group byの処理順序-

公開日: : CakePHP, IT


CakePHPでorder byとgroup byを使っていてはまったことについてのメモ。

 環境

  • MySQL
  • PHP5
  • CakePHP1.3

 やりたいこと

最新巻(no)、設定ID(config_id)、発売日(salesdate)があるテーブルがあるとします。

テーブル構成/データ(例)

idnoconfig_id salesdate
1 1 12011-11-12
2 2 12012-02-10
3 1 22012-01-04
4 1 32011-08-04
5 2 32011-12-03

このデータをconfig_idでグルーピングして、そのconfig_idの最新巻がいくつか知りたい。
つまり求める形は以下。

idnoconfig_id salesdate
2 2 12012-02-10
3 1 22012-01-04
5 2 32011-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
        )
)

これで、なんとか使える形になりました。

 参考サイト

広告

関連記事

スクリーンショット 2012-12-06 15.34.43

iPhoneアプリ開発 -端末がネットワークにつながっているかどうか知りたい-

* やりたいこと アプリがネットに繋がっていなければアラートボックスを表示させたい。 ネットに繋

記事を読む

Jenkins + DeployGate(2) -DeployGateにアプリをアップ!-

DeployGateを使ってますか? 継続的にDeployってますか? TestFlightの

記事を読む

no image

iPhoneアプリ開発 -UIScrollViewで画像を拡大・縮小-

* やりたいこと UIScrollViewでピンチアウト・インして上に乗っている画像を拡大・縮小した

記事を読む

iPhoneアプリ開発 芳名帳アプリ作成(2) -記帳画面作成-

* 今までの流れ - * 画面構成 今回の芳名帳アプリは以下の画面で構成しています。 -

記事を読む

no image

iPhoneアプリ開発 -mixiSDKを使ってmixi連携をしてみる(2)-

* 前回 は、「ユーザーにAPI利用のための認可」をおこなってもらうところまでやりました。 本エン

記事を読む

no image

研究室での進捗報告の方法について、ふと思ったこと

* 以下に加筆・修正して移動しました。

記事を読む

no image

iPhoneアプリ開発 −2本指で画像を移動させる−

* やりたいこと 表示させている画像(UIImageView)を2本指で移動させたい。 ※1本指は別

記事を読む

sample1

jQuery Mobile1.2のCollapsible Listsを試してみた -画像のカスタマイズについて-

8月1日にjQuery Mobile1.2 Alphaが出ました。 まだAlphaなので自

記事を読む

no image

複数アカウントでgithubを使う

1つの端末で複数のアカウントを使いたくなったので、その方法を整理してみた。 流れとしては以下のとおり

記事を読む

no image

Objective-cで悩んでいたこと −アクセサのことについて−

* 疑問 以前書いたiPhoneアプリを開発していて(Objective-Cを触っていて)疑問に思

記事を読む

広告

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

広告

no image
[感想] Effective Objective-C 2.0 ☆☆☆☆★(4.5)

* 構成 - 第1章 Objective-Cに慣れる -

no image
[感想] iOSアプリテスト自動化入門 ☆☆☆(3.0)

* 構成 - Chapter 1 テスト自動化への取り組み

DeployGateを試してみた(iOS編) -DeployGateがiOSに対応-

今までのDeployGate - -[http://pplace.

iPhone/iPadアプリを開発するためにやったこと

今までに、iPhoneを3本ほどリリース((リリースしたアプリは全て1

no image
ターミナルでgitのコマンドを補完したりブランチ名を表示する – macでgitを便利に使うために –

* やりたいこと macのターミナルでgitをいじっていると -今の

→もっと見る

PAGE TOP ↑