← Назад к вопросам

Что такое WHERE в SQL?

1.0 Junior🔥 81 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

WHERE в SQL

WHERE — это фундаментальное предложение (clause) в SQL, которое используется для фильтрации данных в результирующем наборе запроса. Оно позволяет указать условия, которым должны удовлетворять строки из таблицы, чтобы быть включёнными в результат SELECT, UPDATE или DELETE операций.

Основной синтаксис

SELECT с WHERE:

SELECT column1, column2, ...
FROM table_name
WHERE condition;

Примеры условий:

-- Простое равенство
SELECT * FROM employees WHERE department_id = 5;

-- Неравенство
SELECT * FROM products WHERE price > 100;

-- Логические операторы
SELECT * FROM orders WHERE status = 'pending' AND created_at > '2024-01-01';

Операторы сравнения

Числовые операторы:

-- Равно
SELECT * FROM employees WHERE salary = 50000;

-- Не равно
SELECT * FROM employees WHERE salary != 50000;
SELECT * FROM employees WHERE salary <> 50000;

-- Больше / Меньше
SELECT * FROM orders WHERE amount > 1000;
SELECT * FROM products WHERE stock < 10;

-- Больше или равно / Меньше или равно
SELECT * FROM employees WHERE salary >= 60000;
SELECT * FROM users WHERE age <= 18;

Текстовые операторы:

-- Точное совпадение
SELECT * FROM users WHERE first_name = 'John';

-- Чувствительность к регистру зависит от collation
SELECT * FROM users WHERE LOWER(first_name) = 'john';

-- Использование LIKE (шаблоны)
SELECT * FROM users WHERE email LIKE '%@gmail.com';
SELECT * FROM products WHERE name LIKE 'iPhone%';
SELECT * FROM employees WHERE last_name LIKE '_mith'; -- один символ

Логические операторы

AND - оба условия должны быть истинны:

SELECT * FROM employees 
WHERE department_id = 5 AND salary > 50000;

-- Несколько условий
SELECT * FROM orders 
WHERE status = 'completed' 
  AND created_at > '2024-01-01' 
  AND total_amount > 1000;

OR - хотя бы одно условие должно быть истинным:

SELECT * FROM users 
WHERE first_name = 'John' OR first_name = 'Jane';

SELECT * FROM products 
WHERE category = 'electronics' OR price > 500;

NOT - отрицание условия:

SELECT * FROM employees WHERE NOT department_id = 5;
SELECT * FROM products WHERE NOT status = 'inactive';

Комбинация операторов:

SELECT * FROM orders 
WHERE (status = 'completed' OR status = 'shipped') 
  AND created_at > '2024-01-01' 
  AND total_amount > 500;

Специальные операторы WHERE

IN - проверка наличия в списке:

SELECT * FROM employees 
WHERE department_id IN (1, 2, 3, 5);

SELECT * FROM orders 
WHERE status IN ('pending', 'processing', 'shipped');

BETWEEN - диапазон значений:

SELECT * FROM products WHERE price BETWEEN 100 AND 500;

SELECT * FROM orders 
WHERE created_at BETWEEN '2024-01-01' AND '2024-12-31';

IS NULL / IS NOT NULL - проверка на NULL:

SELECT * FROM users WHERE middle_name IS NULL;

SELECT * FROM orders WHERE deleted_at IS NOT NULL;

EXISTS - проверка наличия подзапроса:

SELECT * FROM users u 
WHERE EXISTS (
  SELECT 1 FROM orders o WHERE o.user_id = u.id AND o.total > 1000
);

WHERE в Java с помощью SQL параметров

Использование PreparedStatement (защита от SQL инъекций):

public User findByEmail(String email) throws SQLException {
    String query = "SELECT * FROM users WHERE email = ?";
    
    try (PreparedStatement stmt = connection.prepareStatement(query)) {
        stmt.setString(1, email);
        try (ResultSet rs = stmt.executeQuery()) {
            if (rs.next()) {
                return mapRowToUser(rs);
            }
        }
    }
    return null;
}

ПЛОХО - SQL инъекция:

// НИКОГДА ТАК НЕ ДЕЛАЙ!
public User findByEmail(String email) throws SQLException {
    String query = "SELECT * FROM users WHERE email = '" + email + "'";
    // Уязвимо для SQL инъекции!
    Statement stmt = connection.createStatement();
    return stmt.executeQuery(query);
}

WHERE с JOIN

Фильтрация после объединения таблиц:

SELECT u.id, u.email, o.order_id, o.total
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE u.created_at > '2024-01-01' AND o.total > 100;

В Java с ORM (Hibernate):

public List<User> findActiveUsersWithOrders() {
    return session.createQuery(
        "FROM User u " +
        "JOIN u.orders o " +
        "WHERE u.active = true AND o.status = 'completed'",
        User.class
    ).list();
}

WHERE с подзапросами (Subqueries)

Фильтрация по результатам подзапроса:

-- Найти все заказы пользователей из определённого города
SELECT * FROM orders 
WHERE user_id IN (
    SELECT id FROM users WHERE city = 'New York'
);

-- Найти продукты дороже средней цены
SELECT * FROM products 
WHERE price > (SELECT AVG(price) FROM products);

В Java с JPA:

@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
    @Query("SELECT o FROM Order o WHERE o.user.city = :city")
    List<Order> findOrdersByUserCity(@Param("city") String city);
    
    @Query("SELECT o FROM Order o WHERE o.total > " +
           "(SELECT AVG(o2.total) FROM Order o2)")
    List<Order> findOrdersAboveAverage();
}

Performance и индексы

Индексы значительно ускоряют WHERE:

-- Создание индекса
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_orders_user_status ON orders(user_id, status);

-- Без индекса - полное сканирование таблицы (медленно)
SELECT * FROM users WHERE email = 'user@example.com'; -- O(n)

-- С индексом - быстрый поиск (логарифмический)
SELECT * FROM users WHERE email = 'user@example.com'; -- O(log n)

WHERE в UPDATE и DELETE

UPDATE с условием:

UPDATE employees 
SET salary = salary * 1.1 
WHERE department_id = 5 AND years_of_service > 5;

DELETE с условием:

-- БУДЬ ОСТОРОЖЕН!
DELETE FROM users WHERE active = false AND deleted_at < DATE_SUB(NOW(), INTERVAL 30 DAY);

В Java:

public void deactivateOldInactiveUsers() {
    String query = "UPDATE User u SET u.active = false " +
                   "WHERE u.lastLogin < CURRENT_DATE - 90";
    
    Query q = entityManager.createQuery(query);
    q.executeUpdate();
}

Best Practices

1. Используй параметризованные запросы:

@Query("SELECT u FROM User u WHERE u.email = :email")
User findByEmail(@Param("email") String email);

2. Добавляй индексы на часто используемые WHERE колонки:

CREATE INDEX idx_active_users ON users(active) WHERE active = true;

3. Избегай функций на левой стороне WHERE (блокируют индексы):

-- ПЛОХО
WHERE LOWER(email) = 'test@example.com';

-- ХОРОШО
WHERE email = 'test@example.com';

4. Будь осторожен с NULL:

WHERE age IS NULL;     -- Правильно
WHERE age = NULL;      -- НИКОГДА не работает!

Заключение

WHERE — это критически важное предложение в SQL, которое позволяет эффективно фильтровать данные. Правильное использование WHERE с индексами, параметризованными запросами и логическими операторами обеспечивает как производительность, так и безопасность приложения.

Что такое WHERE в SQL? | PrepBro