【Laravel】クエリビルダによるSQL実行

2024 年 9 月 30 日 by sumitanik

クエリビルダとは

クエリビルダは、データベースからレコードを取得する際にSQL文を組み立て、簡単に問い合わせを行うことができる機能です。

内部結合や外部結合などを含む基本的なSELECT文は、以下のサイトを参照してください。

https://readouble.com/laravel/8.x/ja/queries.html

ここでは、以下のSELECT文を取得する方法について紹介します。
1. IN句に予め取得したCollectionを設定する方法
2. FROM句にSELECT文を設定する方法

IN句に予め取得したCollectionを設定する

SQLのIN句では、特定の列が指定した複数の値のいずれかと一致するかどうかを確認するために使用します。
以下にSQLの例文を示します。

アメリカに住む顧客の注文を全て取得するSQL文

SELECT 
    order_id, 
    order_date, 
    customer_id
FROM 
    orders
WHERE 
    customer_id IN (
        SELECT 
            customer_id
        FROM 
            customers
        WHERE 
            country = 'USA'
    );

上記のSQL文をクエリビルダで実現する場合、IN句に指定する値は以下のようにサブクエリを設定します。

IN句にサブクエリを設定するクエリビルダ

//アメリカに住む顧客の顧客IDを取得するクエリ
$customersQuery = DB::table('customers')
    ->select(
        'customer_id'
    )
    ->where([
        ['country', '=', 'USA']
    ]);

//クエリで取得した顧客IDの注文を全て取得する
$orders = DB::table('orders')
    ->select(
        'order_id',
        'order_date',
        'customer_id'
    )
    ->whereIn('customer_id', $customersQuery)
    ->get();

また、予めget()で取得したCollectionを指定することも可能です。

IN句に Collection を設定するクエリビルダ

//アメリカに住む顧客の顧客IDを取得する
$customers = DB::table('customers')
    ->select(
        'customer_id'
    )
    ->where([
        ['country', '=', 'USA']
    ])
    ->get();

//取得した顧客IDの注文を全て取得する
$orders = DB::table('orders')
    ->select(
        'order_id',
        'order_date',
        'customer_id'
    )
    ->whereIn('customer_id', $customers->pluck('customer_id'))
    ->get();

FROM句にSELECT文を設定する

次に、FROM句にSELECT文を設定した副問い合わせを用いる方法について紹介します。
以下にSQLの例文を示します。

最新の注文のみを取得するSQL文

SELECT
    *
FROM (
    SELECT 
        customer_id, 
        order_id, 
        order_date
    FROM 
        orders
    ORDER BY 
        order_date DESC
) AS recent_orders
WHERE 
    ROWNUM = 1;

上記のSQLをクエリビルダで実現する場合、FROM句に設定するSELECT文を予めサブクエリで取得した上で、DB::tableの引数に取得したサブクエリを設定します。

FROM句にSELECT文を設定するクエリビルダ

//全注文を注文日の降順で取得するクエリ
$recentOrdersQuery = DB::table('orders')
    ->select(
        'customer_id', 
        'order_id', 
        'order_date'
    )
    ->orderBy('order_date', 'desc');

//クエリで取得した注文の最新(1件目)のみ取得する
$orders = DB::table($recentOrdersQuery, DB::raw('recent_orders'))
    ->select(
        '*'
    )
    ->whereRaw('ROWNUM = 1')
    ->get();

まとめ

この記事では、複雑なSELECT文をLaravelのクエリビルダを使用して実装する方法を紹介しました。
今回紹介した手法を活用することで、複雑なデータ取得をシンプルに実装でき、Laravelでのデータベース操作がより効率的になります。
今後もクエリビルダを利用したデータ操作のさらなる活用方法を探求していきたいと思います。

タグ: , ,

TrackBack