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

Где используешь WHERE?

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

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

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

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

Где используешь WHERE

WHERE — это ключевое слово SQL для фильтрации данных в запросах. Используется с SELECT, UPDATE и DELETE операциями.

SELECT с WHERE

Основное применение — фильтрация результатов запроса.

// SQL
SELECT * FROM users WHERE age > 18 AND status = 'ACTIVE';

// JPA Repository
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByAgeGreaterThanAndStatus(int age, String status);
}

// Использование
List<User> adults = repository.findByAgeGreaterThanAndStatus(18, "ACTIVE");

Условия WHERE

Сравнение (=, !=, <, >, <=, >=)

// SQL: WHERE salary >= 50000
List<Employee> highPaid = repository.findBySalaryGreaterThanEqual(50000);

LIKE для текстового поиска

// SQL: WHERE name LIKE '%John%'
List<User> found = repository.findByNameContaining("John");

// SQL: WHERE email LIKE 'user@%.com'
List<User> gmail = repository.findByEmailEndingWith("@gmail.com");

IN для множественных значений

// SQL: WHERE status IN ('ACTIVE', 'PENDING')
List<Order> orders = repository.findByStatusIn(Arrays.asList("ACTIVE", "PENDING"));

NULL проверка

// SQL: WHERE deleted_at IS NULL
List<User> active = repository.findByDeletedAtIsNull();

// SQL: WHERE deleted_at IS NOT NULL
List<User> deleted = repository.findByDeletedAtIsNotNull();

WHERE с @Query

@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
    
    // Простой WHERE
    @Query("SELECT p FROM Product p WHERE p.price > :minPrice")
    List<Product> findExpensive(@Param("minPrice") double minPrice);
    
    // Сложные условия
    @Query("SELECT p FROM Product p WHERE p.category = :cat AND p.inStock = true")
    List<Product> findByCategory(@Param("cat") String category);
    
    // WHERE с JOIN
    @Query("SELECT p FROM Product p JOIN p.reviews r WHERE r.rating >= :minRating")
    List<Product> findHighRated(@Param("minRating") int rating);
}

UPDATE с WHERE

Обновление данных с условиями.

// SQL: UPDATE users SET status = 'INACTIVE' WHERE age > 65
update users set status = 'INACTIVE' where age > 65;

// JPA
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    @Modifying
    @Transactional
    @Query("UPDATE User u SET u.status = 'INACTIVE' WHERE u.age > :age")
    int deactivateOldUsers(@Param("age") int age);
}

// Использование
@Service
public class UserService {
    @Autowired
    private UserRepository repository;
    
    public void archiveOldUsers() {
        int updated = repository.deactivateOldUsers(65);
        System.out.println("Обновлено: " + updated);
    }
}

DELETE с WHERE

Удаление данных с условиями.

// SQL: DELETE FROM orders WHERE status = 'CANCELLED' AND created_at < '2023-01-01'
delete from orders where status = 'CANCELLED' and created_at < '2023-01-01';

// JPA
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
    @Modifying
    @Transactional
    @Query("DELETE FROM Order o WHERE o.status = 'CANCELLED' AND o.createdAt < :date")
    int deleteOldCancelled(@Param("date") LocalDateTime date);
}

// Использование
@Service
public class OrderService {
    @Autowired
    private OrderRepository repository;
    
    public void cleanup() {
        LocalDateTime cutoff = LocalDateTime.now().minusMonths(6);
        int deleted = repository.deleteOldCancelled(cutoff);
    }
}

WHERE с OR условиями

// SQL: WHERE status = 'ACTIVE' OR status = 'PENDING'
@Query("SELECT u FROM User u WHERE u.status = :status1 OR u.status = :status2")
List<User> findActiveOrPending(
    @Param("status1") String status1,
    @Param("status2") String status2
);

// Или используй IN
@Query("SELECT u FROM User u WHERE u.status IN (:statuses)")
List<User> findByStatuses(@Param("statuses") List<String> statuses);

WHERE с агрегацией

// SQL: SELECT COUNT(*) FROM orders WHERE status = 'COMPLETED'
long completed = repository.countByStatus("COMPLETED");

// SQL: SELECT SUM(amount) FROM orders WHERE user_id = :userId
@Query("SELECT SUM(o.amount) FROM Order o WHERE o.user.id = :userId")
BigDecimal getTotalByUser(@Param("userId") Long userId);

WHERE с BETWEEN

// SQL: WHERE price BETWEEN 100 AND 1000
List<Product> products = repository.findByPriceBetween(100.0, 1000.0);

// Дата диапазон
@Query("SELECT o FROM Order o WHERE o.createdAt BETWEEN :start AND :end")
List<Order> findByDateRange(
    @Param("start") LocalDateTime start,
    @Param("end") LocalDateTime end
);

WHERE с подзапросом

// SQL: WHERE user_id IN (SELECT id FROM users WHERE age > 30)
@Query("SELECT o FROM Order o WHERE o.user.id IN " +
       "(SELECT u.id FROM User u WHERE u.age > :age)")
List<Order> findOrdersByAdultUsers(@Param("age") int age);

// EXISTS подзапрос
@Query("SELECT u FROM User u WHERE EXISTS " +
       "(SELECT 1 FROM Order o WHERE o.user.id = u.id AND o.amount > :minAmount)")
List<User> findUsersWithLargeOrders(@Param("minAmount") BigDecimal amount);

WHERE с использованием CASE

@Query("SELECT CASE WHEN COUNT(o) > 0 THEN 1 ELSE 0 END " +
       "FROM Order o WHERE o.user.id = :userId AND o.status = 'COMPLETED'")
int hasCompletedOrders(@Param("userId") Long userId);

Оптимизация WHERE запросов

1. Используй индексы

CREATE INDEX idx_users_status ON users(status);
CREATE INDEX idx_orders_date ON orders(created_at);

2. Избегай функций в WHERE (замедляют индексы)

// ПЛОХО: функция блокирует индекс
@Query("SELECT u FROM User u WHERE UPPER(u.name) = :name")

// ХОРОШО: используй LIKE с правильным регистром
@Query("SELECT u FROM User u WHERE u.name = :name")

3. Порядок условий важен

// Выполняй самые селективные условия первыми
// ХОРОШО: сначала редкое условие, потом частое
WHERE status = 'CANCELLED' AND age > 18

// ПЛОХО: сначала частое, потом редкое
WHERE age > 18 AND status = 'CANCELLED'

Практический пример

@Service
public class OrderSearchService {
    @Autowired
    private OrderRepository repository;
    
    public List<Order> searchOrders(OrderFilter filter) {
        // Комплексный WHERE с множественными условиями
        return repository.findOrders(
            filter.getUserId(),
            filter.getMinAmount(),
            filter.getStatus(),
            filter.getStartDate(),
            filter.getEndDate()
        );
    }
}

@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
    @Query("SELECT o FROM Order o WHERE " +
           "(:userId IS NULL OR o.user.id = :userId) AND " +
           "(:minAmount IS NULL OR o.amount >= :minAmount) AND " +
           "(:status IS NULL OR o.status = :status) AND " +
           "(:startDate IS NULL OR o.createdAt >= :startDate) AND " +
           "(:endDate IS NULL OR o.createdAt <= :endDate)")
    List<Order> findOrders(
        @Param("userId") Long userId,
        @Param("minAmount") BigDecimal minAmount,
        @Param("status") String status,
        @Param("startDate") LocalDateTime startDate,
        @Param("endDate") LocalDateTime endDate
    );
}

Заключение

WHERE используется:

  • SELECT — для фильтрации результатов запроса
  • UPDATE — для выбора записей для обновления
  • DELETE — для выбора записей для удаления

Это одна из самых важных частей SQL запросов в Java приложениях. Правильное использование WHERE определяет производительность и правильность получаемых данных.

Где используешь WHERE? | PrepBro