Как сделать UPDATE с подзапросами в SQLite

    В SQLite часто возникает задача обновить строки одной таблицы на основе данных из других таблиц. Для этого используются вложенные запросы (подзапросы) в конструкции UPDATE. Рассмотрим корректный синтаксис и практические примеры.

    Синтаксис UPDATE с подзапросами в SQLite

    Базовая команда выглядит так:

    UPDATE main_table
    SET column1 = value1
    WHERE main_table.id IN (SELECT id FROM related_table WHERE condition);

    Вместо IN можно использовать EXISTS, если нужно проверить наличие связанных записей.

    Пример: обновление заказов по статусу клиента

    Допустим, есть таблицы orders и customers. Нужно установить скидку 10% для всех заказов клиентов из Москвы:

    UPDATE orders
    SET discount = 10
    WHERE customer_id IN (
        SELECT id FROM customers
        WHERE city = 'Москва'
    );

    Этот запрос обновит только те строки orders, для которых customer_id совпадает с результатом подзапроса.

    Использование EXISTS для сложных условий

    Если нужно обновить строки, удовлетворяющие нескольким условиям из разных таблиц, применяйте EXISTS:

    UPDATE products
    SET price = price * 1.1
    WHERE EXISTS (
        SELECT 1 FROM categories
        WHERE categories.id = products.category_id
        AND categories.name = 'Электроника'
    );

    Здесь обновление происходит только для товаров, у которых категория - «Электроника».

    Обновление с JOIN (только в SQLite 3.33+)

    Начиная с версии SQLite 3.33.0 (2020-08-14) поддерживается синтаксис UPDATE ... FROM, аналогичный JOIN:

    UPDATE orders
    SET status = 'processed'
    FROM customers
    WHERE orders.customer_id = customers.id
    AND customers.rating > 4;

    Это более читаемый способ для сложных связей, но требует актуальной версии SQLite.

    Типичные ошибки и их решение

    • Ошибка: подзапрос возвращает NULL - используйте COALESCE или проверку на IS NOT NULL.
    • Ошибка: обновление всех строк - всегда проверяйте условие WHERE перед выполнением.
    • Ошибка: слишком медленный запрос - добавьте индексы на столбцы, участвующие в подзапросе.

    Заключение

    Обновление строк в SQLite с помощью подзапросов - мощный инструмент для массовых изменений. Используйте IN или EXISTS в зависимости от логики, а для новых версий - UPDATE ... FROM. Всегда тестируйте запрос на копии данных.

    Часто задаваемые вопросы