LoginSignup
0
0

More than 1 year has passed since last update.

CakePHP4 ORM "FROM サブクエリ"

Posted at

環境

PHP 8.1.4RC1
CakePHP 4.3.6

CakePHP4 の ORM で "FROM サブクエリ" を作る

やりたいこと

SELECT base.id
FROM (SELECT h.id FROM hoges h) base
LEFT JOIN moges m ON base.id = m.id

をORMで生成する。

次のコードは最初に書いたもの。

\App\Model\Table\HogeTable
public function getData()
{
    // SELECT h.id FROM hoge h をつくる
    $this->setAlias('h');
    $subquery = $this->find()->select('h.id');

    // サブクエリをFROMに指定する
    $this->belongsTo('m', [
        'className'  => 'Moge',
        'bindingKey' => ['id'],
        'foreignKey' => ['id'],
        'joinType'   => 'LEFT',
    ]);
    $this->setAlias('base');
    $data = $this->find()
                 ->from(['base' => $subquery])
                 ->contain('m')
                 ->select('base.id')
                 ->all();
}

これを実行するとこうなる。

SELECT base.id AS base__id
FROM (SELECT h.id AS h__id FROM hoges base) base
LEFT JOIN moges m ON base.id = m.id

baseidというカラムがない(h__idになっている)
サブクエリの別名もbaseになっている。

問題点

  • カラムの別名は未指定だと、ルールに従い自動で付与される。
  • クエリを発行しないとテーブルの別名は上書きされる。

どーーしてもサブクエリと違う別名を使いたいのであれば
サブクエリを確定(発行)してしまうか、別のTableオブジェクトを使う。

$this->setAlias('h');
$subquery = $this->find()->select(['id' => 'h.id'])->sql();
// SQL発行 => SELECT h.id AS id FROM hoges h

ただこれをfromに指定すると
SELECT base.id FROM SELECT h.id AS id FROM hoges h LEFT JOIN moge m ON
となる(括弧がつかない)し、結果的に文字列を扱うなら最初から無理にORMでやらなくてもよくない?

対処法

というわけで、解決?策。

\App\Model\Table\HogeTable
public function getData()
{
    $sub = clone $this;
    $sub->setAlias('h');
    $subquery = $sub->find()->select(['id' => 'h.id']);

    $this->belongsTo('m', [
        'className'  => 'Moge',
        'bindingKey' => ['id'],
        'foreignKey' => ['id'],
        'joinType'   => 'LEFT',
    ]);
    $this->setAlias('base');
    $data = $this->find()
                 ->from(['base' => $subquery])
                 ->contain('m')
                 ->select('base.id')
                 ->all();
}

結果

SELECT base.id AS base__id
FROM (SELECT h.id AS id FROM hoges h) base
LEFT JOIN moges m ON base.id = m.id

余談

調べたらautoAlias(false)というものを見かけたが、2015年の記事だし、そんなものはなかった。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0