<? phpukraine ДОКУМЕНТАЦІЯ
Пошук по платформі
Документація українською

Переклад офіційної документації українською. Кожен розділ показує стан готовності: недоперекладене позначене відкрито, а не приховане.

ВЕРСІЯ
АКТУАЛЬНА Актуальний реліз. Переклад наздоганяє оригінал, розділи з низьким відсотком позначені у змісті.
БАЗА ДАНИХ · ЧАСТКОВО частковий переклад, оновлено 15 вересня 2026

Query Builder · Laravel

ПЕРЕКЛАД НЕПОВНИЙ

Частину підрозділів ще не перекладено, вони показані англійською нижче в тексті або лишились в оригіналі. Готові фрагменти вже перевірені редактором.

Конструктор запитів (query builder) Laravel дає зручний плавний інтерфейс для створення й виконання запитів до бази даних. Ним можна виконати більшість операцій з базою у вашому застосунку, і він однаково добре працює з усіма СУБД, які підтримує Laravel.

Конструктор запитів Laravel використовує привʼязку параметрів PDO, щоб захистити застосунок від SQL-інʼєкцій. Рядки, які передаються в конструктор як привʼязки запиту, не потрібно окремо очищати чи екранувати.

Увага! PDO не підтримує привʼязку назв стовпців. Тому ніколи не дозволяйте користувацькому вводу визначати назви стовпців у ваших запитах, зокрема стовпців у «order by».

Виконання запитів до бази даних

Отримання всіх рядків таблиці

Щоб почати запит, скористайтеся методом table фасаду DB. Метод table повертає плавний екземпляр конструктора запитів для вказаної таблиці, до якого можна додавати умови ланцюжком і врешті отримати результати методом get:

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\DB;
use Illuminate\View\View;

class UserController extends Controller
{
    /**
     * Показати список усіх користувачів застосунку.
     */
    public function index(): View
    {
        $users = DB::table('users')->get();

        return view('user.index', ['users' => $users]);
    }
}

Метод get повертає екземпляр Illuminate\Support\Collection з результатами запиту, де кожен результат є екземпляром PHP-обʼєкта stdClass. Значення кожного стовпця доступне як властивість обʼєкта:

use Illuminate\Support\Facades\DB;

$users = DB::table('users')->get();

foreach ($users as $user) {
    echo $user->name;
}

Примітка. Колекції Laravel мають багато потужних методів для перетворення й згортання даних. Докладніше про колекції Laravel читайте в документації по колекціях.

Отримання одного рядка або стовпця з таблиці

Якщо потрібно отримати з таблиці лише один рядок, скористайтеся методом first фасаду DB. Цей метод поверне один обʼєкт stdClass:

$user = DB::table('users')->where('name', 'John')->first();

return $user->email;

Якщо ви хочете отримати один рядок із таблиці, але викинути Illuminate\Database\RecordNotFoundException, коли відповідного рядка немає, скористайтеся методом firstOrFail. Якщо RecordNotFoundException не перехоплено, клієнту автоматично надсилається HTTP-відповідь 404:

$user = DB::table('users')->where('name', 'John')->firstOrFail();

Якщо цілий рядок вам не потрібен, можна дістати з запису одне значення методом value. Цей метод повертає значення стовпця напряму:

$email = DB::table('users')->where('name', 'John')->value('email');

Щоб отримати один рядок за значенням стовпця id, використовуйте метод find:

$user = DB::table('users')->find(3);

Отримання списку значень стовпця

Якщо вам потрібен екземпляр Illuminate\Support\Collection зі значеннями одного стовпця, скористайтеся методом pluck. У цьому прикладі отримаємо колекцію посад користувачів:

use Illuminate\Support\Facades\DB;

$titles = DB::table('users')->pluck('title');

foreach ($titles as $title) {
    echo $title;
}

Другим аргументом методу pluck можна вказати стовпець, значення якого стануть ключами результівної колекції:

$titles = DB::table('users')->pluck('title', 'name');

foreach ($titles as $name => $title) {
    echo $title;
}

Обробка результатів частинами

Якщо вам треба працювати з тисячами записів, погляньте на метод chunk фасаду DB. Він отримує невелику порцію результатів за раз і передає кожну порцію в замикання для обробки. Наприклад, пройдімо всю таблицю users порціями по 100 записів:

use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;

DB::table('users')->orderBy('id')->chunk(100, function (Collection $users) {
    foreach ($users as $user) {
        // ...
    }
});

Обробку наступних порцій можна зупинити, повернувши з замикання false:

DB::table('users')->orderBy('id')->chunk(100, function (Collection $users) {
    // Обробляємо записи...

    return false;
});

Якщо під час обробки частинами ви оновлюєте записи в базі, вміст порцій може змінитися неочікуваним чином. Коли ви плануєте оновлювати отримані записи, завжди краще використовувати метод chunkById. Він автоматично розбиває результати на сторінки за первинним ключем запису:

DB::table('users')->where('active', false)
    ->chunkById(100, function (Collection $users) {
        foreach ($users as $user) {
            DB::table('users')
                ->where('id', $user->id)
                ->update(['active' => true]);
        }
    });

Оскільки методи chunkById і lazyById додають до запиту власні умови «where», ваші власні умови варто логічно згрупувати всередині замикання:

DB::table('users')->where(function ($query) {
    $query->where('credits', 1)->orWhere('credits', 2);
})->chunkById(100, function (Collection $users) {
    foreach ($users as $user) {
        DB::table('users')
            ->where('id', $user->id)
            ->update(['credits' => 3]);
    }
});

Увага! Коли ви оновлюєте або видаляєте записи всередині колбека chunk, будь-які зміни первинного або зовнішніх ключів можуть вплинути на запит порції. Через це частина записів може не потрапити в результати.

Ліниве потокове читання результатів

Метод lazy працює схоже на метод chunk: він теж виконує запит порціями. Але замість передавання кожної порції в колбек метод lazy() повертає LazyCollection, тож із результатами можна працювати як з єдиним потоком:

use Illuminate\Support\Facades\DB;

DB::table('users')->orderBy('id')->lazy()->each(function (object $user) {
    // ...
});

Знову ж таки, якщо ви плануєте оновлювати отримані записи під час ітерації, краще взяти методи lazyById або lazyByIdDesc. Вони автоматично розбивають результати на сторінки за первинним ключем запису:

DB::table('users')->where('active', false)
    ->lazyById()->each(function (object $user) {
        DB::table('users')
            ->where('id', $user->id)
            ->update(['active' => true]);
    });

Увага! Коли ви оновлюєте або видаляєте записи під час ітерації по них, будь-які зміни первинного або зовнішніх ключів можуть вплинути на запит порції. Через це частина записів може не потрапити в результати.

Агрегати

Конструктор запитів також має набір методів для отримання агрегатних значень: count, max, min, avg і sum. Будь-який із них можна викликати після побудови запиту:

use Illuminate\Support\Facades\DB;

$users = DB::table('users')->count();

$price = DB::table('orders')->max('price');

Звісно, ці методи можна поєднувати з іншими умовами, щоб точніше налаштувати обчислення агрегату:

$price = DB::table('orders')
    ->where('finalized', 1)
    ->avg('price');

Перевірка наявності записів

Замість методу count для перевірки, чи є записи, що відповідають умовам запиту, скористайтеся методами exists і doesntExist:

if (DB::table('orders')->where('finalized', 1)->exists()) {
    // ...
}

if (DB::table('orders')->where('finalized', 1)->doesntExist()) {
    // ...
}

Вирази SELECT

Визначення секції select

Не завжди потрібно вибирати всі стовпці таблиці. Методом select можна задати власну секцію «select» для запиту:

use Illuminate\Support\Facades\DB;

$users = DB::table('users')
    ->select('name', 'email as user_email')
    ->get();

Метод distinct змушує запит повертати лише унікальні результати:

$users = DB::table('users')->distinct()->get();

Якщо у вас уже є екземпляр конструктора запитів і ви хочете додати стовпець до наявної секції select, скористайтеся методом addSelect:

$query = DB::table('users')->select('name');

$users = $query->addSelect('age')->get();

Сирі вирази

Іноді потрібно вставити в запит довільний рядок. Щоб створити сирий рядковий вираз, використовуйте метод raw фасаду DB:

$users = DB::table('users')
    ->select(DB::raw('count(*) as user_count, status'))
    ->where('status', '<>', 1)
    ->groupBy('status')
    ->get();

Увага! Сирі вирази вставляються в запит як рядки, тому будьте вкрай обережні, щоб не створити вразливість до SQL-інʼєкцій.

Сирі методи

Замість методу DB::raw можна використовувати наведені нижче методи для вставки сирого виразу в різні частини запиту. Памʼятайте: Laravel не може гарантувати, що запит із сирими виразами захищений від SQL-інʼєкцій.

selectRaw

Метод selectRaw можна використовувати замість addSelect(DB::raw(/* ... */)). Другим аргументом він приймає необовʼязковий масив привʼязок:

$orders = DB::table('orders')
    ->selectRaw('price * ? as price_with_tax', [1.0825])
    ->get();

whereRaw / orWhereRaw

Методи whereRaw і orWhereRaw вставляють у запит сиру секцію «where». Другим аргументом вони приймають необовʼязковий масив привʼязок:

$orders = DB::table('orders')
    ->whereRaw('price > IF(state = "TX", ?, 100)', [200])
    ->get();

havingRaw / orHavingRaw

Методи havingRaw і orHavingRaw дають змогу передати сирий рядок як значення секції «having». Другим аргументом вони приймають необовʼязковий масив привʼязок:

$orders = DB::table('orders')
    ->select('department', DB::raw('SUM(price) as total_sales'))
    ->groupBy('department')
    ->havingRaw('SUM(price) > ?', [2500])
    ->get();

orderByRaw

Метод orderByRaw дає змогу передати сирий рядок як значення секції «order by»:

$orders = DB::table('orders')
    ->orderByRaw('updated_at - created_at DESC')
    ->get();

groupByRaw

Метод groupByRaw дає змогу передати сирий рядок як значення секції group by:

$orders = DB::table('orders')
    ->select('city', 'state')
    ->groupByRaw('city, state')
    ->get();

Обʼєднання (joins)

Секція inner join

Конструктор запитів також уміє додавати до запитів секції join. Для звичайного «inner join» викличте метод join на екземплярі конструктора. Перший аргумент join - назва таблиці, яку треба приєднати, решта аргументів задають умови приєднання за стовпцями. В одному запиті можна приєднати навіть кілька таблиць:

use Illuminate\Support\Facades\DB;

$users = DB::table('users')
    ->join('contacts', 'users.id', '=', 'contacts.user_id')
    ->join('orders', 'users.id', '=', 'orders.user_id')
    ->select('users.*', 'contacts.phone', 'orders.price')
    ->get();

Секція left join / right join

Якщо замість «inner join» потрібен «left join» чи «right join», використовуйте методи leftJoin або rightJoin. Вони мають ту саму сигнатуру, що й метод join:

$users = DB::table('users')
    ->leftJoin('posts', 'users.id', '=', 'posts.user_id')
    ->get();

$users = DB::table('users')
    ->rightJoin('posts', 'users.id', '=', 'posts.user_id')
    ->get();

Секція cross join

Метод crossJoin виконує «cross join». Такі приєднання дають декартів добуток між першою таблицею і приєднаною:

$sizes = DB::table('sizes')
    ->crossJoin('colors')
    ->get();

Складніші секції join

Можна задавати й складніші умови приєднання. Для цього передайте замикання другим аргументом методу join. Замикання отримає екземпляр Illuminate\Database\Query\JoinClause, через який ви задаєте обмеження секції «join»:

DB::table('users')
    ->join('contacts', function (JoinClause $join) {
        $join->on('users.id', '=', 'contacts.user_id')->orOn(/* ... */);
    })
    ->get();

Якщо в приєднанні потрібна секція «where», скористайтеся методами where і orWhere екземпляра JoinClause. Замість порівняння двох стовпців ці методи порівнюють стовпець зі значенням:

DB::table('users')
    ->join('contacts', function (JoinClause $join) {
        $join->on('users.id', '=', 'contacts.user_id')
            ->where('contacts.user_id', '>', 5);
    })
    ->get();

Приєднання підзапитів

Методи joinSub, leftJoinSub і rightJoinSub приєднують запит до підзапиту. Кожен із них приймає три аргументи: підзапит, його псевдонім таблиці та замикання, яке визначає повʼязані стовпці. У цьому прикладі отримаємо колекцію користувачів, де кожен запис також містить мітку часу created_at останнього опублікованого допису користувача:

$latestPosts = DB::table('posts')
    ->select('user_id', DB::raw('MAX(created_at) as last_post_created_at'))
    ->where('is_published', true)
    ->groupBy('user_id');

$users = DB::table('users')
    ->joinSub($latestPosts, 'latest_posts', function (JoinClause $join) {
        $join->on('users.id', '=', 'latest_posts.user_id');
    })->get();

Латеральні приєднання (lateral joins)

Увага! Латеральні приєднання наразі підтримують PostgreSQL, MySQL >= 8.0.14 і SQL Server.

Методи joinLateral і leftJoinLateral виконують «lateral join» з підзапитом. Кожен із них приймає два аргументи: підзапит і його псевдонім таблиці. Умови приєднання задаються в секції where самого підзапиту. Латеральні приєднання обчислюються для кожного рядка і можуть посилатися на стовпці поза підзапитом.

У цьому прикладі ми отримаємо колекцію користувачів разом із трьома останніми дописами кожного. Кожен користувач може дати до трьох рядків у результаті: по одному на кожен зі своїх останніх дописів. Умова приєднання задана секцією whereColumn усередині підзапиту з посиланням на поточний рядок користувача:

$latestPosts = DB::table('posts')
    ->select('id as post_id', 'title as post_title', 'created_at as post_created_at')
    ->whereColumn('user_id', 'users.id')
    ->orderBy('created_at', 'desc')
    ->limit(3);

$users = DB::table('users')
    ->joinLateral($latestPosts, 'latest_posts')
    ->get();

Обʼєднання запитів (unions)

Конструктор запитів має зручний метод для обʼєднання («union») двох чи більше запитів. Наприклад, можна створити початковий запит і методом union обʼєднати його з іншими запитами:

use Illuminate\Support\Facades\DB;

$usersWithoutFirstName = DB::table('users')
    ->whereNull('first_name');

$users = DB::table('users')
    ->whereNull('last_name')
    ->union($usersWithoutFirstName)
    ->get();

Крім методу union, конструктор запитів надає метод unionAll. Запити, обʼєднані через unionAll, зберігають дублікати результатів. Сигнатура unionAll збігається з сигнатурою union.

Базові секції where

Секції where

Щоб додати до запиту секції «where», скористайтеся методом where конструктора запитів. Найпростіший виклик where потребує трьох аргументів. Перший - назва стовпця. Другий - оператор, будь-який з підтримуваних вашою базою. Третій - значення, з яким порівнюється значення стовпця.

Наприклад, наступний запит отримує користувачів, у яких значення стовпця votes дорівнює 100, а значення стовпця age більше за 35:

$users = DB::table('users')
    ->where('votes', '=', 100)
    ->where('age', '>', 35)
    ->get();

Для зручності, якщо потрібно перевірити рівність (=) стовпця заданому значенню, передайте значення другим аргументом методу where. Laravel вважатиме, що ви хочете оператор =:

$users = DB::table('users')->where('votes', 100)->get();

Методу where можна передати й асоціативний масив, щоб швидко зробити запит одразу по кількох стовпцях:

$users = DB::table('users')->where([
    'first_name' => 'Jane',
    'last_name' => 'Doe',
])->get();

Як уже згадувалося, можна використовувати будь-який оператор, який підтримує ваша СУБД:

$users = DB::table('users')
    ->where('votes', '>=', 100)
    ->get();

$users = DB::table('users')
    ->where('votes', '<>', 100)
    ->get();

$users = DB::table('users')
    ->where('name', 'like', 'T%')
    ->get();

Функції where можна також передати масив умов. Кожен елемент масиву має бути масивом із трьох аргументів, які зазвичай передають методу where:

$users = DB::table('users')->where([
    ['status', '=', '1'],
    ['subscribed', '<>', '1'],
])->get();

Увага! PDO не підтримує привʼязку назв стовпців. Тому ніколи не дозволяйте користувацькому вводу визначати назви стовпців у ваших запитах, зокрема стовпців у «order by».

Увага! MySQL і MariaDB автоматично приводять рядки до цілих чисел у порівняннях «рядок - число». При цьому нечислові рядки перетворюються на 0, що призводить до несподіваних результатів. Наприклад, якщо в таблиці є стовпець secret зі значенням aaa, а ви виконаєте User::where('secret', 0), цей рядок буде повернуто. Щоб цього уникнути, приводьте всі значення до відповідних типів перед використанням у запитах.

Секції or where

Коли ви ланцюжком викликаєте метод where конструктора запитів, секції «where» зʼєднуються оператором and. Проте метод orWhere приєднує умову до запиту оператором or. Метод orWhere приймає ті самі аргументи, що й where:

$users = DB::table('users')
    ->where('votes', '>', 100)
    ->orWhere('name', 'John')
    ->get();

Якщо потрібно згрупувати умову «or» у дужках, передайте замикання першим аргументом методу orWhere:

use Illuminate\Database\Query\Builder;

$users = DB::table('users')
    ->where('votes', '>', 100)
    ->orWhere(function (Builder $query) {
        $query->where('name', 'Abigail')
            ->where('votes', '>', 50);
        })
    ->get();

Приклад вище дасть такий SQL:

select * from users where votes > 100 or (name = 'Abigail' and votes > 50)

Увага! Завжди групуйте виклики orWhere, щоб уникнути несподіваної поведінки при застосуванні глобальних скоупів.

Секції where not

Методи whereNot і orWhereNot заперечують задану групу умов запиту. Наприклад, наступний запит виключає товари, які є в розпродажі або мають ціну менше десяти:

$products = DB::table('products')
    ->whereNot(function (Builder $query) {
        $query->where('clearance', true)
            ->orWhere('price', '<', 10);
        })
    ->get();

Секції where any / all / none

Іноді ті самі умови треба застосувати до кількох стовпців. Наприклад, отримати всі записи, де будь-який зі стовпців списку відповідає LIKE заданому значенню. Для цього є метод whereAny:

$users = DB::table('users')
    ->where('active', true)
    ->whereAny([
        'name',
        'email',
        'phone',
    ], 'like', 'Example%')
    ->get();

Запит вище дасть такий SQL:

SELECT *
FROM users
WHERE active = true AND (
    name LIKE 'Example%' OR
    email LIKE 'Example%' OR
    phone LIKE 'Example%'
)

Так само метод whereAll дозволяє отримати записи, де всі задані стовпці відповідають умові:

$posts = DB::table('posts')
    ->where('published', true)
    ->whereAll([
        'title',
        'content',
    ], 'like', '%Laravel%')
    ->get();

Запит вище дасть такий SQL:

SELECT *
FROM posts
WHERE published = true AND (
    title LIKE '%Laravel%' AND
    content LIKE '%Laravel%'
)

Метод whereNone дозволяє отримати записи, де жоден із заданих стовпців не відповідає умові:

$albums = DB::table('albums')
    ->where('published', true)
    ->whereNone([
        'title',
        'lyrics',
        'tags',
    ], 'like', '%explicit%')
    ->get();

Запит вище дасть такий SQL:

SELECT *
FROM albums
WHERE published = true AND NOT (
    title LIKE '%explicit%' OR
    lyrics LIKE '%explicit%' OR
    tags LIKE '%explicit%'
)

Секції where для JSON

Laravel підтримує запити до стовпців типу JSON у базах, які мають такі типи. Наразі це MariaDB 10.3+, MySQL 8.0+, PostgreSQL 12.0+, SQL Server 2017+ і SQLite 3.39.0+. Для запиту до JSON-стовпця використовуйте оператор ->:

$users = DB::table('users')
    ->where('preferences->dining->meal', 'salad')
    ->get();

$users = DB::table('users')
    ->whereIn('preferences->dining->meal', ['pasta', 'salad', 'sandwiches'])
    ->get();

Для запитів до JSON-масивів є методи whereJsonContains і whereJsonDoesntContain:

$users = DB::table('users')
    ->whereJsonContains('options->languages', 'en')
    ->get();

$users = DB::table('users')
    ->whereJsonDoesntContain('options->languages', 'en')
    ->get();

Якщо ваш застосунок працює з MariaDB, MySQL або PostgreSQL, методам whereJsonContains і whereJsonDoesntContain можна передати масив значень:

$users = DB::table('users')
    ->whereJsonContains('options->languages', ['en', 'de'])
    ->get();

$users = DB::table('users')
    ->whereJsonDoesntContain('options->languages', ['en', 'de'])
    ->get();

Крім того, методи whereJsonContainsKey і whereJsonDoesntContainKey дозволяють отримати результати, які містять або не містять певний JSON-ключ:

$users = DB::table('users')
    ->whereJsonContainsKey('preferences->dietary_requirements')
    ->get();

$users = DB::table('users')
    ->whereJsonDoesntContainKey('preferences->dietary_requirements')
    ->get();

Нарешті, метод whereJsonLength дозволяє робити запити до JSON-масивів за їхньою довжиною:

$users = DB::table('users')
    ->whereJsonLength('options->languages', 0)
    ->get();

$users = DB::table('users')
    ->whereJsonLength('options->languages', '>', 1)
    ->get();

Додаткові секції where

whereLike / orWhereLike / whereNotLike / orWhereNotLike

Метод whereLike додає до запиту секції «LIKE» для пошуку за шаблоном. Ці методи дають незалежний від СУБД спосіб виконувати пошук за рядками з можливістю вмикати чутливість до регістру. Типово пошук нечутливий до регістру:

$users = DB::table('users')
    ->whereLike('name', '%John%')
    ->get();

Увімкнути чутливий до регістру пошук можна аргументом caseSensitive:

$users = DB::table('users')
    ->whereLike('name', '%John%', caseSensitive: true)
    ->get();

Метод orWhereLike додає секцію «or» з умовою LIKE:

$users = DB::table('users')
    ->where('votes', '>', 100)
    ->orWhereLike('name', '%John%')
    ->get();

Метод whereNotLike додає до запиту секції «NOT LIKE»:

$users = DB::table('users')
    ->whereNotLike('name', '%John%')
    ->get();

Так само orWhereNotLike додає секцію «or» з умовою NOT LIKE:

$users = DB::table('users')
    ->where('votes', '>', 100)
    ->orWhereNotLike('name', '%John%')
    ->get();

Увага! Опція чутливого до регістру пошуку в whereLike наразі не підтримується на SQL Server.

whereIn / whereNotIn / orWhereIn / orWhereNotIn

Метод whereIn перевіряє, що значення стовпця міститься в заданому масиві:

$users = DB::table('users')
    ->whereIn('id', [1, 2, 3])
    ->get();

Метод whereNotIn перевіряє, що значення стовпця не міститься в заданому масиві:

$users = DB::table('users')
    ->whereNotIn('id', [1, 2, 3])
    ->get();

Другим аргументом методу whereIn можна передати й обʼєкт запиту:

$activeUsers = DB::table('users')->select('id')->where('is_active', 1);

$comments = DB::table('comments')
    ->whereIn('user_id', $activeUsers)
    ->get();

Приклад вище дасть такий SQL:

select * from comments where user_id in (
    select id
    from users
    where is_active = 1
)

Увага! Якщо ви додаєте до запиту великий масив привʼязок цілих чисел, методи whereIntegerInRaw або whereIntegerNotInRaw суттєво зменшать споживання памʼяті.

whereBetween / orWhereBetween

Метод whereBetween перевіряє, що значення стовпця перебуває між двома значеннями:

$users = DB::table('users')
    ->whereBetween('votes', [1, 100])
    ->get();

whereNotBetween / orWhereNotBetween

Метод whereNotBetween перевіряє, що значення стовпця лежить поза двома значеннями:

$users = DB::table('users')
    ->whereNotBetween('votes', [1, 100])
    ->get();

whereBetweenColumns / whereNotBetweenColumns / orWhereBetweenColumns / orWhereNotBetweenColumns

Метод whereBetweenColumns перевіряє, що значення стовпця перебуває між значеннями двох стовпців того самого рядка таблиці:

$patients = DB::table('patients')
    ->whereBetweenColumns('weight', ['minimum_allowed_weight', 'maximum_allowed_weight'])
    ->get();

Метод whereNotBetweenColumns перевіряє, що значення стовпця лежить поза значеннями двох стовпців того самого рядка таблиці:

$patients = DB::table('patients')
    ->whereNotBetweenColumns('weight', ['minimum_allowed_weight', 'maximum_allowed_weight'])
    ->get();

whereValueBetween / whereValueNotBetween / orWhereValueBetween / orWhereValueNotBetween

Метод whereValueBetween перевіряє, що задане значення перебуває між значеннями двох стовпців одного типу в тому самому рядку таблиці:

$products = DB::table('products')
    ->whereValueBetween(100, ['min_price', 'max_price'])
    ->get();

Метод whereValueNotBetween перевіряє, що значення лежить поза значеннями двох стовпців того самого рядка таблиці:

$products = DB::table('products')
    ->whereValueNotBetween(100, ['min_price', 'max_price'])
    ->get();

whereNull / whereNotNull / orWhereNull / orWhereNotNull

Метод whereNull перевіряє, що значення заданого стовпця дорівнює NULL:

$users = DB::table('users')
    ->whereNull('updated_at')
    ->get();

Метод whereNotNull перевіряє, що значення стовпця не дорівнює NULL:

$users = DB::table('users')
    ->whereNotNull('updated_at')
    ->get();

whereNullSafeEquals / orWhereNullSafeEquals

Методи whereNullSafeEquals і orWhereNullSafeEquals порівнюють значення стовпця із заданим значенням, вважаючи два значення NULL рівними:

$lastLoginIp = $request->input('last_login_ip');

$users = DB::table('users')
    ->whereNullSafeEquals('last_login_ip', $lastLoginIp)
    ->get();

whereDate / whereMonth / whereDay / whereYear / whereTime

Метод whereDate порівнює значення стовпця з датою:

$users = DB::table('users')
    ->whereDate('created_at', '2016-12-31')
    ->get();

Метод whereMonth порівнює значення стовпця з конкретним місяцем:

$users = DB::table('users')
    ->whereMonth('created_at', '12')
    ->get();

Метод whereDay порівнює значення стовпця з конкретним днем місяця:

$users = DB::table('users')
    ->whereDay('created_at', '31')
    ->get();

Метод whereYear порівнює значення стовпця з конкретним роком:

$users = DB::table('users')
    ->whereYear('created_at', '2016')
    ->get();

Метод whereTime порівнює значення стовпця з конкретним часом:

$users = DB::table('users')
    ->whereTime('created_at', '=', '11:20:45')
    ->get();

wherePast / whereFuture / whereToday / whereBeforeToday / whereAfterToday

Методи wherePast і whereFuture перевіряють, чи значення стовпця в минулому або в майбутньому:

$invoices = DB::table('invoices')
    ->wherePast('due_at')
    ->get();

$invoices = DB::table('invoices')
    ->whereFuture('due_at')
    ->get();

Методи whereNowOrPast і whereNowOrFuture перевіряють, чи значення стовпця в минулому або майбутньому, включно з поточними датою й часом:

$invoices = DB::table('invoices')
    ->whereNowOrPast('due_at')
    ->get();

$invoices = DB::table('invoices')
    ->whereNowOrFuture('due_at')
    ->get();

Методи whereToday, whereBeforeToday і whereAfterToday перевіряють, чи значення стовпця припадає на сьогодні, до сьогодні або після сьогодні відповідно:

$invoices = DB::table('invoices')
    ->whereToday('due_at')
    ->get();

$invoices = DB::table('invoices')
    ->whereBeforeToday('due_at')
    ->get();

$invoices = DB::table('invoices')
    ->whereAfterToday('due_at')
    ->get();

Так само методи whereTodayOrBefore і whereTodayOrAfter перевіряють, чи значення стовпця припадає на час до сьогодні або після сьогодні, включно з сьогоднішньою датою:

$invoices = DB::table('invoices')
    ->whereTodayOrBefore('due_at')
    ->get();

$invoices = DB::table('invoices')
    ->whereTodayOrAfter('due_at')
    ->get();

whereColumn / orWhereColumn

Метод whereColumn перевіряє рівність двох стовпців:

$users = DB::table('users')
    ->whereColumn('first_name', 'last_name')
    ->get();

Методу whereColumn можна також передати оператор порівняння:

$users = DB::table('users')
    ->whereColumn('updated_at', '>', 'created_at')
    ->get();

Ще методу whereColumn можна передати масив порівнянь стовпців. Ці умови зʼєднуються оператором and:

$users = DB::table('users')
    ->whereColumn([
        ['first_name', '=', 'last_name'],
        ['updated_at', '>', 'created_at'],
    ])->get();

Логічне групування

Іноді кілька секцій «where» треба згрупувати в дужках, щоб отримати потрібне логічне групування запиту. Власне, виклики методу orWhere варто завжди брати в дужки, щоб запит не поводився несподівано. Для цього передайте замикання методу where:

$users = DB::table('users')
    ->where('name', '=', 'John')
    ->where(function (Builder $query) {
        $query->where('votes', '>', 100)
            ->orWhere('title', '=', 'Admin');
    })
    ->get();

Як бачите, передане в метод where замикання вказує конструктору запитів почати групу умов. Замикання отримує екземпляр конструктора запитів, через який ви задаєте умови всередині дужок. Приклад вище дасть такий SQL:

select * from users where name = 'John' and (votes > 100 or title = 'Admin')

Увага! Завжди групуйте виклики orWhere, щоб уникнути несподіваної поведінки при застосуванні глобальних скоупів.

Складніші секції where

Секції where exists

Метод whereExists дозволяє писати SQL-секції «where exists». Він приймає замикання, яке отримує екземпляр конструктора запитів, і в ньому ви визначаєте запит, що має опинитися всередині секції «exists»:

$users = DB::table('users')
    ->whereExists(function (Builder $query) {
        $query->select(DB::raw(1))
            ->from('orders')
            ->whereColumn('orders.user_id', 'users.id');
    })
    ->get();

Замість замикання методу whereExists можна передати обʼєкт запиту:

$orders = DB::table('orders')
    ->select(DB::raw(1))
    ->whereColumn('orders.user_id', 'users.id');

$users = DB::table('users')
    ->whereExists($orders)
    ->get();

Обидва приклади вище дадуть такий SQL:

select * from users
where exists (
    select 1
    from orders
    where orders.user_id = users.id
)

Секції where з підзапитами

Іноді потрібно побудувати секцію «where», яка порівнює результати підзапиту з заданим значенням. Для цього передайте методу where замикання і значення. Наприклад, наступний запит отримає всіх користувачів, у яких є свіже «membership» заданого типу:

use App\Models\User;
use Illuminate\Database\Query\Builder;

$users = User::where(function (Builder $query) {
    $query->select('type')
        ->from('membership')
        ->whereColumn('membership.user_id', 'users.id')
        ->orderByDesc('membership.start_date')
        ->limit(1);
}, 'Pro')->get();

Або ж вам може знадобитися секція «where», яка порівнює стовпець із результатами підзапиту. Для цього передайте методу where стовпець, оператор і замикання. Наприклад, наступний запит отримає всі записи про дохід, де сума менша за середню:

use App\Models\Income;
use Illuminate\Database\Query\Builder;

$incomes = Income::where('amount', '<', function (Builder $query) {
    $query->selectRaw('avg(i.amount)')->from('incomes as i');
})->get();

Секції where для повнотекстового пошуку

Увага! Секції where для повнотекстового пошуку наразі підтримують MariaDB, MySQL і PostgreSQL.

Методи whereFullText і orWhereFullText додають до запиту повнотекстові секції «where» для стовпців, які мають повнотекстові індекси. Laravel перетворить їх на відповідний SQL для вашої СУБД. Наприклад, для застосунків на MariaDB чи MySQL буде згенеровано секцію MATCH AGAINST:

$users = DB::table('users')
    ->whereFullText('bio', 'web developer')
    ->get();

Секції векторної подібності

Примітка. Секції векторної подібності наразі підтримуються на зʼєднаннях PostgreSQL із розширенням pgvector і на MariaDB 11.7 та новіших. Про визначення векторних стовпців та індексів читайте в документації по міграціях.

Метод whereVectorSimilarTo фільтрує результати за косинусною подібністю до заданого вектора й упорядковує їх за релевантністю. Поріг minSimilarity має бути значенням між 0.0 і 1.0, де 1.0 означає ідентичність:

$documents = DB::table('documents')
    ->whereVectorSimilarTo('embedding', $queryEmbedding, minSimilarity: 0.4)
    ->limit(10)
    ->get();

Якщо аргументом вектора передано звичайний рядок, Laravel автоматично згенерує для нього ембединги через Laravel AI SDK:

$documents = DB::table('documents')
    ->whereVectorSimilarTo('embedding', 'Best wineries in Napa Valley')
    ->limit(10)
    ->get();

Типово whereVectorSimilarTo також сортує результати за відстанню (найподібніші першими). Це сортування можна вимкнути, передавши false в аргумент order:

$documents = DB::table('documents')
    ->whereVectorSimilarTo('embedding', $queryEmbedding, minSimilarity: 0.4, order: false)
    ->orderBy('created_at', 'desc')
    ->limit(10)
    ->get();

Якщо потрібен більший контроль, використовуйте методи selectVectorDistance, whereVectorDistanceLessThan і orderByVectorDistance окремо:

$documents = DB::table('documents')
    ->select('*')
    ->selectVectorDistance('embedding', $queryEmbedding, as: 'distance')
    ->whereVectorDistanceLessThan('embedding', $queryEmbedding, maxDistance: 0.3)
    ->orderByVectorDistance('embedding', $queryEmbedding)
    ->limit(10)
    ->get();

Для PostgreSQL розширення pgvector має бути завантажене, перш ніж можна створювати стовпці vector:

Schema::ensureVectorExtensionExists();

Сортування, групування, limit і offset

Сортування

Метод orderBy

Метод orderBy сортує результати запиту за заданим стовпцем. Перший аргумент orderBy - стовпець, за яким сортувати, другий задає напрямок сортування і може бути asc або desc:

$users = DB::table('users')
    ->orderBy('name', 'desc')
    ->get();

Щоб сортувати за кількома стовпцями, просто викличте orderBy стільки разів, скільки потрібно:

$users = DB::table('users')
    ->orderBy('name', 'desc')
    ->orderBy('email', 'asc')
    ->get();

Напрямок сортування необовʼязковий, типово він зростаючий. Для спадного сортування вкажіть другий параметр методу orderBy або просто скористайтеся orderByDesc:

$users = DB::table('users')
    ->orderByDesc('verified_at')
    ->get();

Нарешті, через оператор -> результати можна сортувати за значенням усередині JSON-стовпця:

$corporations = DB::table('corporations')
    ->where('country', 'US')
    ->orderBy('location->state')
    ->get();

Методи latest і oldest

Методи latest і oldest дають змогу легко впорядкувати результати за датою. Типово результат сортується за стовпцем created_at таблиці. Або ж можна передати назву стовпця, за яким сортувати:

$user = DB::table('users')
    ->latest()
    ->first();

Випадкове сортування

Метод inRandomOrder сортує результати запиту випадково. Наприклад, ним можна дістати випадкового користувача:

$randomUser = DB::table('users')
    ->inRandomOrder()
    ->first();

Видалення наявних сортувань

Метод reorder прибирає всі секції «order by», застосовані до запиту раніше:

$query = DB::table('users')->orderBy('name');

$unorderedUsers = $query->reorder()->get();

Методу reorder можна передати стовпець і напрямок, щоб прибрати всі наявні секції «order by» і застосувати до запиту цілком нове сортування:

$query = DB::table('users')->orderBy('name');

$usersOrderedByEmail = $query->reorder('email', 'desc')->get();

Для зручності є метод reorderDesc, який пересортовує результати запиту за спаданням:

$query = DB::table('users')->orderBy('name');

$usersOrderedByEmail = $query->reorderDesc('email')->get();

Групування

Методи groupBy і having

Як і очікується, методи groupBy і having групують результати запиту. Сигнатура методу having схожа на сигнатуру where:

$users = DB::table('users')
    ->groupBy('account_id')
    ->having('account_id', '>', 100)
    ->get();

Методом havingBetween можна відфільтрувати результати в заданому діапазоні:

$report = DB::table('orders')
    ->selectRaw('count(id) as number_of_orders, customer_id')
    ->groupBy('customer_id')
    ->havingBetween('number_of_orders', [5, 15])
    ->get();

Методу groupBy можна передати кілька аргументів, щоб групувати за кількома стовпцями:

$users = DB::table('users')
    ->groupBy('first_name', 'status')
    ->having('account_id', '>', 100)
    ->get();

Для складніших виразів having дивіться метод havingRaw.

Limit і offset

Методи limit і offset обмежують кількість повернутих запитом результатів або пропускають задану кількість результатів:

$users = DB::table('users')
    ->offset(10)
    ->limit(5)
    ->get();

Умовні секції

Іноді потрібно застосувати певні секції запиту лише за якоїсь умови. Наприклад, додати вираз where тільки тоді, коли у вхідному HTTP-запиті присутнє певне значення. Для цього є метод when:

$role = $request->input('role');

$users = DB::table('users')
    ->when($role, function (Builder $query, string $role) {
        $query->where('role_id', $role);
    })
    ->get();

Метод when виконує передане замикання лише тоді, коли перший аргумент дорівнює true. Якщо перший аргумент - false, замикання не виконується. Тож у прикладі вище передане в when замикання спрацює лише за умови, що поле role присутнє у вхідному запиті й обчислюється як true.

The following sections have not yet been translated: Insert Statements (including Upserts), Update Statements (including Updating JSON Columns, Increment and Decrement), Delete Statements, Pessimistic Locking, Reusable Query Components, Debugging.

ЯК ЦЯ СТОРІНКА ВИГЛЯДАЄ В ПОШУКУ
phpukraine.com/docs/laravel/queries
Query Builder | Документація Laravel українською
Query Builder у Laravel 13.x: переклад офіційної документації українською. Оновлено 15 вересня 2026. Приклади коду, пояснення та посилання на питання зі співбесід.
Стан перекладу

Перекладаємо з офіційної документації, розділ за розділом, і не ховаємо недоперекладене. Помітили неточність у терміні чи реченні: напишіть, виправимо.

90%
Готовності
10
У роботі
0
Ще не перекладено
Глосарій термінів