今回はLaravelを使う際に重要となるQuery Builder(クエリビルダー)のうち、データの抽出条件を指定するwhere句についてです。
単純なwhere条件から一部を括弧でまとめる方法等、様々な条件の書き方をサンプルコードとしてまとめました。
※Laravelのバージョンは5.6を使用しています。
解説
サンプルのコードで使用している$this->post
には、サンプル用に作成したEloquentのPostモデルのインスタンスが設定されていることとします。
where() – 基本のwhere句
where()は3つの引数を受け取り、第一引数がカラム名、第二引数が演算子、第三引数が第一引数のカラム名に対する値です。
$this->post->where('is_public', '=', '1')
->get();
AND条件を追加する場合は更にwhere()を呼び出します。
$this->post->where('title', '=', 'foobar')
->where('content', 'like', '%bar%')
->get();
OR条件を追加する場合はorWhere()を呼び出します。
$this->post->where('title', 'like', '%foo%')
->orWhere('title', 'like', '%builder%')
->get();
whereIn() – IN句による検索
$this->post->whereIn('id', [1, 2, 3])
->get();
select * from "posts" where "id" in (1, 2, 3)
whereBetween() – 対象のカラムを範囲検索する
あるカラムが持つ値に対して範囲検索をする場合に使用します。
$this->post->whereBetween('id', [1, 100])
->get();
このクエリは下記のSQLを生成します。
select * from "posts" where "id" between 1 and 100
日付に関する検索
whereDate() – 年月日による検索
whereDate()を使うと、created_at
等のtimestamp型のカラムに対して、年月日を使って検索ができます。
例えば下記のように条件を指定することが可能です。
$this->post->whereDate('created_at', '=', '2018-08-03')
->get();
whereYear() – 年を指定した検索
$this->post->whereYear('created_at', '=', '2018')
->get();
whereMonth() – 月を指定した検索
$this->post->whereMonth('created_at', '=', '07')
->get();
whereDay() – 日にちを指定した検索
$posts = $this->post->whereDay('created_at', '1')
->get();
whereTime() – 時間を指定した検索
$this->post->whereTime('created_at', '=', '00:44:33')
->get();
whereColumn() – 指定した2つのカラムを比較
whereColumn()を使うと、第1、第3引数に指定したカラムを比較することが可能です。
下記はcreated_atとupdated_atが一致するかどうかを条件として追加しています。
$this->post->whereColumn('created_at', '=', 'updated_at')
->get();
SELECT *
FROM posts
WHERE created_at = updated_at
;
組み合わせを増やしたい場合は、下記のようにします。
$this->post->whereColumn([
['title', '=', 'content'],
['created_at', '<', 'updated_at']
])->get();
SELECT *
FROM posts
WHERE (title = content AND created_at < updated_at)
;
複数の条件に括弧をつけてまとめる方法
ANDやOR条件を同時に使用する際、条件によっては括弧を付ける必要があります。
例えば次のようなSQLを生成したい場合の書き方を示します。
SELECT *
FROM posts
WHERE "is_public" = 1 OR ("content" LIKE "%foo%" AND "is_public" = 0)
;
こうした場合は、orWhere()にクロージャーを渡します。
クロージャーの引数の$queryはIlluminate\Database\Eloquent\Builderのインスタンスが設定されているため、括弧でまとめたい条件をwhere()等を使って指定することができます。
$this->post->where('is_public', '=', '1')
->orWhere(function ($query) {
return $query->where('content', 'like', '%foo%')
->where('is_public', '=', '0');
})
->get();