Eloquentは便利ですよね。どんなメソッドがあるかまとめたくなったので、ここに書いちゃおうと思います。
*使用環境
PHP 7.4.5
Laravel 7.22.4
#基本的な使い方
まずはモデルクラスを用意します。Itemクラスならば以下のようなコマンドで作れます。
php artisan make:model Item
後はそのモデルクラスを使って、あとで出る表にあるメソッドでどんどんデータ抽出するだけです。こんな感じで->でくっつけていきます。
<?php
use Item; //この一文を書き忘れるとエラーになってしまう。
$result = Item::where('value', 1000)->limit(10)->get();
#一般
メソッド名 | 引数 | 説明 |
---|---|---|
DB::raw | 1.SQL文 | 引数の文字列がそのままSQL文になります。 |
setBindings | 1.プレースホルダの文字列と当てはめるデータの連想配列 | キーがプレースホルダとなっている文字列、値が入れたいデータです。 |
toSql | なし | 実行結果ではなく、SQLとして出力されます。サブクエリを作る時に使います。 |
#参照元(fromで使うような)
メソッド名 | 引数 | 説明 |
---|---|---|
DB::table | 1.テーブル名 | DB::table('ITEM')とすれば、from ITEM ということになります。DB::table('ITEM as i')というようにasを後ろに付けると別名をあてることができます。 |
#集計系(selectで使うような)
メソッド名 | 引数 | 説明 |
---|---|---|
get | 1.カラム名配列 | get()ですべてなのでselect *になります。引数として取り出したいカラム名を配列で入れるとそのカラムのデータのみになります。 |
first | 1.カラム名配列 | get()と同じように使いますが、1件だけ取ってきます。主キー検索した時などに使います。 |
select | 1~.カラム名 | select('item_name', 'value')というようにいくつでも付けられます。ただし、その後でget()やfirst()を使わないと思い通りにデータが取れません。(何やらあらゆる情報がくっついてくるみたいです。) |
max | 1.カラム名 | max('value')とすればselect max(value)ということになります。 |
count | 引数なし | count()とすればselect count(*)ということになります。(注1) |
(注1)get()->count()と書くと、select *になってしまうらしいです。 | ||
https://www.larajapan.com/2016/06/19/eloquentでカウントするときの注意/ | ||
(注2)カラム名を別名にしたい時はよくあると思います。こんな時は、get()の引数の配列内の文字列を'【カラム名】 as 【別名】'の書き方にするとできます。例えば、「user_id」というカラム名を「id」にしたいのであれば、 | ||
get(['user_id as id']) |
||
というように書けばできます。bladeの方では、「【結果の変数名】->id」で出てきます。 | ||
(残念ながら「【結果の変数名】->customer.user_id」みたいな書き方はエラーになってしまいます。ドットが使えないということですかね。) |
#結合系(joinを使うような)
メソッド名 | 引数 | 説明 |
---|---|---|
join | 1.テーブル名 2.主となるテーブルの結合カラム 3.演算子(=など) 4.従となるテーブルの結合カラム | join('type', 'item.item_type', '=', 'type.id')とすれば、inner join type on item.item_type = type.idということになります。 |
(注3)joinに関して、第1引数のテーブル名の所を「【テーブル名】 as 【別名】」と書くとテーブル名に別名を付けることができます。例えば、item_masterをitemにしたいのであれば「item_master as item」となります。get()と同じですね。 |
#抽出系(whereで使うような)
メソッド名 | 引数 | 説明 |
---|---|---|
where | 1.カラム名 2.完全一致させるもの | where('id', 'solabito331')とすればwhere id='solabito331'という抽出のしかたになります。 |
where | 1.カラム名 2.演算子(=など) 3.比較対象 | where('id', '>', 10)とすればwhere id>10 という抽出のしかたになります。 |
whereNotNull | 1.カラム名 | whereNotNull('age')とすれば、where age is not nullという抽出のしかたになります。 |
limit | 1.件数 | limit(10)とすれば、10件に絞られます。 |
#複雑な結合
2020.9.22追記
上にあるようなjoin()を使うと、1つの結合条件に関して結合ができますが、複数の結合条件を使いたいという時はどうしたらいい?これに関しては、クロージャ―を使います。
#こんな書き方をしたい時
##SELECT COUNT()
2021.9.2追記
「SELECT COUNT(*) AS TOTAL_COLUMN FROM ITEM」に相当するものを書きたい時は以下のような感じになります。get("COUNT() AS TOTAL_COUNT")と書いてもエラーになるので注意。
//Itemクラスを作成しているものとする。
Item::select(DB::raw("COUNT(*) AS TOTAL_COLUMN"))->get("TOTAL_COUNT");
##サブクエリをFROM句で使うようなSQL
2021.9.15追記
次のようなSQLを書きたいとします。
(売上のデータがあって、品目IDが1000以下の品目ごとの売り上げ個数を出すのがサブクエリ。売上個数0個はいくつの品目であった、売上個数1個はいくつの品目であった…というものを出すのが全体のクエリという想定です。)
SELECT SUB.SOLD_COUNT
,COUNT(*) AS ITEM_COUNT
FROM (
SELECT ITEM_ID
,COUNT(*) AS SOLD_COUNT
FROM SALE
GROUP BY ITEM_ID
WHERE SUB.ITEM_ID < 1000
) AS SUB
GROUP BY SUB.SOLD_COUNT
この場合は次のような感じになります。
//Saleクラスを作成しているものとする。
$subQuery = Sale::where("ITEM_ID", "<", ":ITEM_ID")
->groupBy("ITEM_ID")
->select("ITEM_ID",
DB::raw("COUNT(*) AS SOLD_COUNT"))
->toSql();
$result = DB::table(DB::raw("(" . $subQuery . "AS SUB)")
->setBindings([":ITEM_ID"=>"1000"])
->groupBy("SUB.SOLD_COUNT")
->select("SUB.SOLD_COUNT",
DB::raw("COUNT(*) AS ITEM_COUNT"))
->get();
注意
1. where("ITEM_ID", "<", 1000)というような書き方はエラーになってしまうようです。プレースホルダを置いて、setBindings()を使いましょう。ちなみに、エラーメッセージは「SQLSTATE[HY000]: General error: 2031」です。(あまり内容が具体的でない上に、SQLは正しく見えるので知らないとハマる!)
*サブクエリのプレースホルダに何も入れないままSQLを生成しているためだと思います。
2. table()で、"("と")"を忘れずに。サブクエリをくくるための括弧になります。
*参考:[PHP][Laravel][SQL] LaravelのEloquentでFROM句の副問い合わせ
##UNION
2021.12.19追記
まずは1つのSELECTした結果を変数に入れます。その後でUNIONしたいSELECT処理を行った後でunionすればできます。
$query1 = ItemMain::where('ITEM_CD')
->select('ITEM_CD', 'ITEM_NAME');
$query2 = ItemSub::where('ITEM_CD')
->select('ITEM_CD', 'ITEM_NAME')
->union($query1)
->get();