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

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

 参考サイト

広告

関連記事

no image

Jenkins+Capistranoを設定した時にしたこと -「ポート変更」「公開鍵認証」対応-

* 前段階 上記にあるように、Jenkins+Capistranoの設定をしています。 ただし、設

記事を読む

no image

iPhoneアプリ開発 芳名帳アプリ作成(6) -写真に保存-

* 今までの流れ - -[http://pplace.jp/2013/06/1531/:title=

記事を読む

Jenkins + iPhoneアプリ(番外1) -TestFlightを利用する-

* これまで - -- 執事(Jenkins)を雇いました。 * やりたいこと Jenk

記事を読む

no image

リンク文字をタッチしても色が変わらない --webkit-tap-highlight-colorのメモ-

* 背景 jQuery Mobileを利用してスマートフォン対応をしたサイトにおいてリンク文字をタッ

記事を読む

no image

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

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

記事を読む

no image

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

* やりたいこと macのターミナルでgitをいじっていると -今のブランチってなんだっけ? -g

記事を読む

Jenkins + スマホアプリ(1) -スマホアプリ用CI環境を作ってみよう-

前回までは、iPhoneアプリでのCI環境でした。 TestFlightがAndroidアプリにも

記事を読む

no image

jQuery Mobileでミスしたこと -JSだけ最新にしてしまってレイアウト崩れたの巻-

* 前提(CDN先) jQuery Mobileを使う場合、cssを自前のサーバにおいて、jsはC

記事を読む

mixisample

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

* やりたいこと iPhoneアプリでmixiと連携し、mixiボイスなどに文字を投稿する。 ※

記事を読む

no image

Androidアプリ開発 -リストをタッチして別ページ表示-

* 前提 -「設定画面」で各種項目を設定。 --Activity:ConfigActivity --

記事を読む

広告

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 ↑