day13(?)の今日はUNIONクエリを実行する方法を見ていきます。
Doctrine
<?php
declare(strict_types=1);
use App\Entity\Author;
use App\Entity\Book;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\ResultSetMapping;
require __DIR__.'/../vendor/autoload.php';
/** @var EntityManagerInterface $entityManager */
$entityManager = require __DIR__.'/bootstrap.php';
/** @var array<array{id: int, name: string}> $rows */
$rows = $entityManager->getConnection()->fetchAllAssociative('SELECT id, name FROM authors UNION SELECT id, title FROM books');
- 複数のテーブルにまたがるunionの場合はエンティティにマップしてもしょうがないのでDBALを使ってarrayを取得します。
- 単一のテーブルで異なる条件のSQL同士をUNIONしたい場合はNativeQueryを使ってエンティティにマップすることもできます。
Eloquent
<?php
declare(strict_types=1);
use App\Models\Author;
use App\Models\Book;
use Illuminate\Database\Eloquent\Collection;
require __DIR__.'/../vendor/autoload.php';
/** @var Collection<Author> $authors */
$authors = Author::query()
->select('id', 'name')
->union(Book::query()->select('id', 'title'))
->get()
;
// $authorsにはid, nameのみを持つAuthorモデルのインスタンスと、booksテーブルのid, title(nameという名前で収納される)を持つAuthorモデルのインスタンスが混在したコレクション
- Eloquentのunion機能を使った場合、BookモデルのデータであってもAuthorモデルにマップされます。(ちょっと気持ち悪いですね )
-
DB::statement()
を使うことで生SQLのUNIONクエリを実行し、arrayの形でレコードを得ることもできます。