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

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

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

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

Q&A

解決済

1回答

8621閲覧

cakephp3 関連あるテーブルのデータ取得 matching と innerJoinWith の違いについて疑問があります

blossan

総合スコア154

CakePHP

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

0グッド

1クリップ

投稿2016/10/19 00:55

お世話になります。
以前こちらで、「関連あるテーブルのデータ取得方法」を教えていただきました。
以下のリファレンスを参照することで、

関連付くデータでフィルタする

関連付くデータでの取得方法を学びました。

その際に、複数階層があるものは、matching ではなく、innerJoinWith を使うという説明を受けました。複数階層があるという具体例は、以下のようなものを想定しています。

Users テーブルには、Article テーブルという記事テーブルと繋がり、さらに Article テーブルは、Tags テーブルという記事のタグ情報と繋がっている場合を想定します

ただ、参考サイトでは、

cakephp3

1 $query = $products->find()->matching( 2 'Shops.Cities.Countries', function ($q) { 3 return $q->where(['Countries.name' => 'Japan']); 4 } 5 );

matching でも、深い階層を取得しているような気がします。
参考サイトの解説では、

matching() 関数を使うことで、すでに見てきたように、特定の関連との INNER JOIN が作成され、 結果セットにもフィールドがロードされます。

matching() を使いたいものの、結果セットにフィールドをロードしたくない状況もあるかもしれません。 この目的で innerJoinWith() を使うことが出来ます。

という説明され、イメージとしては、matching では、テーブルが全て合体し、例えば以下の場合、

cakephp3

1 $query = $products->find()->matching( 2 'Shops.Cities.Countries', function ($q) { 3 return $q->where(['Countries.name' => 'Japan']); 4 } 5 );

条件によって抽出された日本製品の商品だけでなく、それに付随する[Shops],[Cities],[Countries]も取得できるという意味だと考えています。

逆にinnerJoinWithでは、条件によって抽出された日本製品の情報だけ、この場合、[Products]テーブル内のデータしか取得できないという考察をしました。

しかし、matching は inner join をする、その名前が含まれる innerJoinWith は、inner join はしないというややこしい状態で、私の考えが正しいのかわかりません。
解説をお願いしたいです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

実際にやってみましたが、matchingでも多段階層の条件できますね(勉強不足ですみませんでした)

なお、innerJoinWithとmatchingの違いですが、ほとんど違いはないようです。

matching() を使いたいものの、結果セットにフィールドをロードしたくない状況もあるかもしれません。 この目的で innerJoinWith() を使うことが出来ます。

この記載の通りで、matchingを使った場合は、_matchingDataという形でJoinした関連データを取得することができるようです。実際Cakeのコードを見てみたら、どちらも同じmatching関数を呼んでいるだけでした。

投稿2016/10/19 02:52

popobot

総合スコア6586

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

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

KiyoshiMotoki

2016/10/19 03:18

icchii様、sakura630様 横から失礼します。 debug() メソッドを使用して matching と innerJoinWith がそれぞれどのようなSQLを生成するか確認してみると、より具体的に違いをイメージできるかも知れません。 http://book.cakephp.org/3.0/ja/orm/query-builder.html#id3 > Query オブジェクトを debug() で使うと、内部の状態とデータベースで実行されることになる SQL が出力されます。 おそらく、matching は  SELECT t1.col1, t1.col2, ... , t2.col1, t2.col2, ... FROM t1 INNER JOIN t2 ON ... のようになるのに対して、 innerJoinWith は  SELECT t1.col1, t1.col2, ... FROM t1 INNER JOIN t2 ON ... のようになる(SELECT 句に t2 のカラムが含まれない)のではないかと推測します。
popobot

2016/10/19 03:29

KiyoshiMotokiさん、コメントありがとうございます。 実際にやってみましたが、仰る通りSQL的には、SELECTのカラム指定が違うだけでした。
KiyoshiMotoki

2016/10/19 03:33

icchii様 検証報告いただき、恐縮です。 私も勉強させていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問