質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

Q&A

解決済

1回答

5793閲覧

CakePHP3 各グループ内の最新レコードを得たい

takingshape

総合スコア10

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

0グッド

1クリップ

投稿2017/03/31 10:30

###前提・実現したいこと
コントローラ内でTableRegistry::getを使用して各物件マスターテーブル(Places)と,その各物件からのレポートが毎日追加されるデータテーブル(Data)を取得しております。

各物件(Placeテーブルの各レコード)に対してDataテーブルの最新のレコード一件を結合させたいのですが,粘りましたが上手く行きませんでしたので,こちらでお教えいただこうと思いました。

グループ化によりどのように最新レコードを取得できるか,お教えいただけたら助かります。

Places
ID
name
name_kana
created
modified
Data
ID
place_id
staff_amount_morning
key_check_morning
staff_amount_evening
key_check_evening
created
modified

###発生している問題・エラーメッセージ

今place_idをグループ化する事でplace_idで紐づくDataテーブルのレコードを一つづつに絞るところまでは出来ました。 しかし,グループ化で抽出されたplace_idグループごとのデータが最新のものに出来ません。 (最新でないデータが選ばれてしまいます。)

###該当のソースコード
↓以下は前述の通り,place_id毎に一つずつDataテーブルから取得できているソースです。

public function initialize() { parent::initialize(); $this->places = TableRegistry::get('Places'); $this->data = TableRegistry::get('Data'); } public function occupancy() { $data = $this->data->find() ->contain(['Places']) ->group('place_id') ->all(); $this->set('data', $data); $this->set('_serialize', ['data']); }

↓以下は上記のソースにhavingで条件を付け足して最大値レコードの取得を試みているものですが,結果は空になってしまいます。

public function initialize() { parent::initialize(); $this->places = TableRegistry::get('Places'); $this->data = TableRegistry::get('Data'); } public function occupancy() { $data = $this->data->find() ->contain(['Places']) ->group('place_id') ->having(['max(Data.id)' => 'Data.id']) ->all(); $this->set('data', $data); $this->set('_serialize', ['data']); }

###試したこと
SQLですとinnerJoinを用いて最新のデータ取得等のソース情報がありましたので,CakePHPの書き方に直してみようと試行錯誤しましたが,どうも的外れの様でマニュアルを見ても上手く組むことが出来ずあきらめました。
恐縮ですが,抽出条件の書き方の基本が残念ながら分かっていないようです。

またCakePHP3のクエリビルダを用いてオプションとしてOrderを記載してIDで降順にすることもしてみましたが,配列の並び替えが変わってしまい,グループ化されるデータの並び替え?には影響しないようでした。素人コメントで申し訳ございません。

###補足情報(言語/FW/ツール等のバージョンなど)
PHP7,CakePHP3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

stackoverflowに類似の質問があり、詳しい解説が載っていましたので参考にしてください。

How to limit contained associations per record/group?

投稿2017/03/31 21:58

編集2017/03/31 21:59
popobot

総合スコア6586

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takingshape

2017/04/04 03:56 編集

教えていただき,どうもありがとうございます。 Model(Table)の方で制限する方法だと理解できました。 大変近い参考情報をありがとうございます。ただ,私の力量ゆえ残念ながらまだ上手く出来ておりません。 Modelの方でDataテーブルをグループごとに1件ずつと制限してしまうと,Controllerの他のアクションでも共有したい場合に困ってしまうように思うのですが,どうなのでしょうか。 (私が知らないだけかもしれません) 今回他のアクションではすべてのDataテーブル情報を取得する必要があるのですが,教えて頂いたサイトの方法(一番参考になるとされている投稿の1-3番目の方法)で組んだ場合,やり方によってはそういう取得を同時に同じモデルから行うことができますでしょうか。
popobot

2017/04/04 05:19

できますよ。 アソシエーションの名前はテーブルクラス名とは別の名前で定義することができます。 最新の1件に絞ったものをLastetDataとして、条件を絞っていないものをDataとして定義すればいいと思います。別の名前をつけた場合、元のクラス名をclassNameというオプションで指定します。 $this->hasOne('LatestData', ['className' => 'Data']);
takingshape

2017/04/10 03:41

お返事が遅くなりましてすみません。 ご親切に教えて下さり、どうもありがとうございます。 時間が無くまだ試せていないのですがこれで出来そうです。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問