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

github-flowを使っての開発(3) -1つのプロジェクトを複数人で開発-

今まで2回ほどgithub-flowをもとにした開発の流れを書きました。 今回は、複数人で開発をする

記事を読む

no image

str_padとsprintfの速度

PHPで同じことが出来る「str_pad」と「sprintf」。 今まではsprintfを使う機会

記事を読む

input

CakePHP2系でTwigを利用 -書き方のメモ-

CakePHP2系でTwigをどのように記述するかのメモ。 数パターンしか載せてないですが、だいた

記事を読む

jenkins-files

Windows環境でもJenkins -執事さんとご対面-

Trac Lightningに同梱されていますし、Windows環境でHudsonを使っている人は結

記事を読む

no image

Facebookがちょっとコワイ vol.2 -本当にあなたはあなたなの?-

以下のブログを読んで、さらにコワイと思ったFacebook。 あなたが登録している「友

記事を読む

mixisample

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

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

記事を読む

no image

さくらのVPSでJenkins -執事さんとご対面-

さくらのVPSを利用している方は多いかと思います。 私も、自分で遊ぶ用(開発用)として借りてみまし

記事を読む

no image

Twitterでプロテクトをかけているユーザが投稿したステータスを取得する方法

* 前提 ID Twitterの各投稿にはIDが存在していています。 そのIDを元にステータス

記事を読む

スクリーンショット 2013-04-27 11.46.12

githubを使っての開発(2) -masterブランチにマージ-

前エントリーでgithub-flowをもとにした流れを書いたのですが、その中のマージについてもう少し

記事を読む

no image

Facebookがちょっとコワイ vol.1 -自分の情報をコントロールできない-

Facebookの最近の広がり方などを見ていて、少々不安を感じたので思ったことをつらつらと書いてみま

記事を読む

広告

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 ↑