| この記事の要点 |
|
基本: whereIn / whereNotIn
use Illuminate\Support\Facades\DB;
use App\Models\User;
// ID 配列で絞り込み (SQL: WHERE id IN (1, 2, 3))
$ids = [1, 2, 3];
$users = User::whereIn('id', $ids)->get();
$users = DB::table('users')->whereIn('id', $ids)->get();
// 否定 (SQL: WHERE status NOT IN (...))
$active = User::whereNotIn('status', ['deleted', 'banned'])->get();
// 空配列を渡すと: whereIn は「常に false」、whereNotIn は「常に true」
User::whereIn('id', [])->get(); // → 必ず空 (WHERE 0=1)
User::whereNotIn('id', [])->get(); // → 全件 (WHERE 1=1)
// サブクエリ
$activeUserIds = User::where('status', 'active')->pluck('id');
$orders = Order::whereIn('user_id', $activeUserIds)->get();
// サブクエリ式
$orders = Order::whereIn('user_id', function ($q) {
$q->select('id')->from('users')->where('status', 'active');
})->get();
複数カラムの IN (whereIn のタプル)
// 標準 SQL: (user_id, product_id) IN ((1, 100), (2, 200))
// Laravel では whereIn にカラム配列を渡せるバージョンあり (DBドライバ依存)
DB::table('orders')->whereIn(['user_id', 'product_id'], [
[1, 100],
[2, 200],
])->get();
// または whereRaw で書く
DB::table('orders')
->whereRaw('(user_id, product_id) IN ((?, ?), (?, ?))', [1, 100, 2, 200])
->get();
複合条件: クロージャでグルーピング
// (name LIKE ? OR email LIKE ?) AND status = 'active'
$users = User::where(function ($q) use ($keyword) {
$q->where('name', 'LIKE', "%{$keyword}%")
->orWhere('email', 'LIKE', "%{$keyword}%");
})
->where('status', 'active')
->get();
// 動的に条件を組み立てる
$query = User::query();
if ($keyword) {
$query->where(function ($q) use ($keyword) {
$q->where('name', 'LIKE', "%{$keyword}%")
->orWhere('email', 'LIKE', "%{$keyword}%");
});
}
if (!empty($statuses)) {
$query->whereIn('status', $statuses);
}
if ($from) $query->where('created_at', '>=', $from);
if ($to) $query->where('created_at', '<=', $to);
$users = $query->orderBy('id')->paginate(20);
配列 (HashMap 風) を where() で展開
// 配列を渡すと AND で連結
$users = User::where([
'status' => 'active',
'role' => 'admin',
'company_id' => 10,
])->get();
// → WHERE status='active' AND role='admin' AND company_id=10
// 各条件に演算子を指定したい場合
$users = User::where([
['age', '>=', 20],
['status', '=', 'active'],
['name', 'LIKE', 'A%'],
])->get();
JSON カラムの配列条件
MySQL 5.7+ / PostgreSQL の JSON / JSONB カラムは専用メソッドで条件指定できます:
// users.preferences = '{"languages": ["ja", "en"]}'
// JSON 配列に特定の値が含まれる
User::whereJsonContains('preferences->languages', 'ja')->get();
// 複数値すべて含む
User::whereJsonContains('preferences->languages', ['ja', 'en'])->get();
// JSON 配列の要素数
User::whereJsonLength('preferences->languages', '>=', 2)->get();
// JSON オブジェクトのキー値
User::where('preferences->theme', 'dark')->get();
// → WHERE JSON_EXTRACT(preferences, '$.theme') = 'dark'
// JSON カラムをアップデート
DB::table('users')
->where('id', 1)
->update(['preferences->theme' => 'light']);
PostgreSQL 配列型カラム
PostgreSQL は配列型 (text[], int[] 等)をネイティブにサポート。ANY / && / @> 演算子で条件指定:
// products.tags TEXT[] (例: ['ja', 'en', 'sale'])
// 'ja' が含まれる
DB::table('products')
->whereRaw("'ja' = ANY(tags)")
->get();
// 配列同士の重なり (1 つでも一致)
DB::table('products')
->whereRaw("tags && ARRAY['ja', 'en']::text[]")
->get();
// 配列の包含 (tags が指定配列を全て含む)
DB::table('products')
->whereRaw("tags @> ARRAY['ja', 'en']::text[]")
->get();
// バインドパラメータ版
DB::table('products')
->whereRaw('? = ANY(tags)', ['ja'])
->get();
IN サブクエリとの比較
| 方式 | 使う場面 | 性能 |
|---|---|---|
whereIn([...]) | 固定配列・少件数 (~ 数千) | 速い |
whereIn(クロージャ) | サブクエリで動的取得 | オプティマイザ次第 |
whereExists | 存在チェック・大量データ | 速い |
JOIN | 関連データ取得も同時に | 速い |
IN(...) 大量パラメータ | ~ 数万件 | パラメータ上限 (MySQL: 65535、Oracle: 1000) に注意 |
性能上の注意
// ❌ 数万件の配列を whereIn → クエリが巨大化
$ids = range(1, 50000);
User::whereIn('id', $ids)->get(); // SQL が数 MB に
// ✅ 一時テーブルに INSERT してから JOIN
DB::statement('CREATE TEMPORARY TABLE tmp_ids (id BIGINT PRIMARY KEY)');
DB::table('tmp_ids')->insert(array_map(fn($id) => ['id' => $id], $ids));
$users = DB::table('users')
->join('tmp_ids', 'users.id', '=', 'tmp_ids.id')
->get();
// ✅ chunk で分割実行
foreach (array_chunk($ids, 1000) as $chunk) {
User::whereIn('id', $chunk)->each(function ($user) {
// 処理
});
}
// ✅ サブクエリ版 (DB 内で完結)
$users = User::whereIn('id', function ($q) {
$q->select('user_id')->from('orders')->where('status', 'completed');
})->get();
Eloquent の whereHas / whereRelation
// 「アクティブな注文を持つユーザー」
$users = User::whereHas('orders', function ($q) {
$q->where('status', 'active');
})->get();
// Laravel 9+ のショートカット
$users = User::whereRelation('orders', 'status', 'active')->get();
// 注文を 5 件以上持つユーザー
$users = User::has('orders', '>=', 5)->get();
// 注文を持たない
$users = User::doesntHave('orders')->get();
FAQ
Q: 空配列を whereIn に渡すと SQL エラーになる?
A: Laravel は内部で安全に処理し、WHERE 0=1 相当に展開します。何も返らないだけでエラーにはなりません。
Q: whereIn に 1 万件の配列を渡しても大丈夫?
A: MySQL の max_allowed_packet (デフォルト 64MB) を超えるとエラー。Oracle は IN リスト 1000 件上限です。chunk 推奨。
Q: 配列の順序通りに結果を並べたい
A: orderByRaw("FIELD(id, " . implode(',', $ids) . ")") (MySQL)。PostgreSQL は array_position。
子ページ
子ページはありません
同階層のページ
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- プロジェクトをTomcatプロジェクトとして認識させる方法 2026-10-07 22:32:50
- MySQLの1366 Incorrect string value|Laravelの文字コード・絵文字エラー 2026-10-07 21:54:03
- curlの証明書ホスト名不一致|旧エラー51・現行60の確認と対処 2026-10-07 21:54:03
- LaravelのMassAssignmentException|fillableの原因と安全な対処 2026-10-07 21:54:03
- Eclipse で Tomcat の起動ログがコンソールに出ない時の確認手順 2026-10-07 21:54:02
- MySQLにおける中央値(Median)の導き方(バージョン8未満) 2026-10-07 13:49:45
- getInputForward 2026-10-07 13:41:15
- JSONから配列に変換 2026-10-07 13:41:15
- ビューから値をモデルに格納しコントローラーで受け取る方法 2026-10-07 13:23:41
- Laravelのテーブル作成と定義変更|マイグレーション・up/down・注意点 2026-10-07 13:23:41
- NumPy 配列に要素を追加する方法 (append / concatenate) 2026-10-07 13:23:41
- MariaDB・MySQLで現在日時を取得する方法|NOW・タイムゾーン・保存型 2026-10-07 13:13:36
- 【django】テンプレートで定数を使用する方法 2026-10-07 13:10:15
- Spring BootにおけるApplication.propertiesの環境依存設定の分割方法 2026-10-07 12:09:35
- Not supported for DML operations【Springエラー】 2026-10-07 11:09:38