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

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

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

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

Q&A

1回答

4176閲覧

CakePHP3 クエリビルダによる入れ子状JOINテーブルのCOUNTの方法について

yokatone

総合スコア43

CakePHP

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

0グッド

0クリップ

投稿2018/02/20 14:28

分からない事

以下のようなSQLをCakePHP3で取得したいと思っていますが、
公式API及びCookBookを見ても方法が分かりません。
ご存知の方がおられたら教えてください。

想定されるDBは3つテーブルがあり、
A (hasMany)-> C (hasMany)-> Dという順番で結合しています。
Aテーブルはマスターテーブル
CテーブルはAとDを繋ぐためのテーブル
Dテーブルはワークテーブル
といった形です。

マスターテーブルAのIDで、ワークテーブルDのレコード数を数えたい といったものです。
クエリビルダでなくとも、他の方法での解決方法があればそれでもかまいません。

どうぞよろしくお願いいたします。

コード

sql

1select A.id, A.name, count(B.id) from A 2 left join 3 (select C.id, D.a_id from D 4 left join 5 C on D.id = C.d_id 6 ) as B 7 on A.id = B.b_id 8group by A.id;
  • テーブル

|A.id|A.name|
|C.id|C.d_id|
|D.id|D.a_id|

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

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

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

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

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

guest

回答1

0

前提を確認させてください。
A (hasMany)-> C (hasMany)-> Dという順番で結合しています。
CテーブルはAとDを繋ぐためのテーブル
Dテーブルはワークテーブル ですね!

CREATE TABLE A_muster (
id int(11) NOT NULL,
name varchar(48) DEFAULT NULL,
PRIMARY KEY (id)
)

CREATE TABLE C_tbl (
a_id int(11) NOT NULL,
d_id int(11) DEFAULT NULL,
PRIMARY KEY (a_id)
)

CREATE TABLE D_trn (
trn_id int(11) NOT NULL,
id int(11) DEFAULT NULL,
PRIMARY KEY (trn_id)
)
サンプルのデータ
A_muster
id name
1 NM1
2 NM2
3 NM3
4 NM4
5 NM5

C_tbl
a_id d_id
1 11
2 12
3 13
4 14
5 15

D_trn
trn_id id
101 11
102 11
103 12
104 13
105 14
106 14

これからAに対するDの数は
SELECT
A.id,
A.name,
count(D.id)
FROM
A_muster AS A
inner JOIN C_tbl AS C ON A.id = C.a_id
left JOIN D_trn AS D ON C.d_id = D.id
group BY A.id

Aid  A.名称  D.件数
1 NM1 2
2 NM2 1
3 NM3 1
4 NM4 2
5 NM5 0

もしも 0件を 数えないなら
SELECT
A.id,
A.name,
count(D.id)
FROM
A_muster AS A
inner JOIN C_tbl AS C ON A.id = C.a_id
inner JOIN D_trn AS D ON C.d_id = D.id
group BY A.id
ですが いかがでしょうか

cakePHP3では

use Cake\Datasource\ConnectionManager;

<?php // DB接続を取得 $connection = ConnectionManager::get('default'); // SQL $sql = 'SELECT A.id,A.`name`,count(D.id) AS cnt'; $sql.= 'FROM A_muster AS A '; $sql.= 'inner JOIN C_tbl AS C ON A.id = C.a_id '; $sql.= 'left JOIN D_trn AS D ON C.d_id = D.id '; $sql.= 'group BY A.id '; // 実行 $query = $connection->execute($sql)->fetchAll('assoc'); foreach ($query as $row) { ?>
<td><?= $row['id'] ?></td> <td><?= $row['name'] ?></td> <td><?= $row['cnt'] ?></td>
<?php } ?>

で できます。

投稿2018/02/21 00:20

GBB00516

総合スコア29

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

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

yokatone

2018/02/22 04:35

すみません.... 順番としてはA->D->Cのほうが適切でした。 ご提示いただいた情報を参考に作ってみたところ、うまくSQLを作れました。ありがとうございます。 SQLを直接記述する方法も教えてくださりありがとうございます。 また、このときですが、今作っているものではビヘイビアを使って論理削除を行っています。 もちろん同様にこのSQLに論理削除の式を入れておけばよいのですが、 なるべくModel情報はシステム内で共通化しておきたいと考えていますので、 質問ばかりで申し訳ございませんが、 $Model->find()メソッドなどでCakePHPらしく実現する方法をご存知でしたら教えてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問