Как получить список уникальных имен в SQL?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
# Как получить список уникальных имён в SQL
Получение уникальных значений — одна из самых частых операций в SQL. Рассмотрю различные способы и когда их использовать.
1. Оператор DISTINCT
Самый простой и распространённый способ:
SELECT DISTINCT name FROM users;
Этот запрос вернёт каждое уникальное имя один раз. Если в таблице есть имена: "Иван", "Мария", "Иван", "Петр", "Мария", то результат будет: "Иван", "Мария", "Петр".
Можно использовать DISTINCT с несколькими полями:
SELECT DISTINCT name, email FROM users;
Вернёт уникальные комбинации имён и emails.
2. GROUP BY
Метод с группировкой более мощный, так как позволяет добавлять агрегирующие функции:
SELECT name FROM users GROUP BY name;
Результат аналогичен DISTINCT, но GROUP BY используется, когда нужны дополнительные вычисления:
SELECT name, COUNT(*) as count FROM users GROUP BY name;
Вернёт каждое уникальное имя и количество пользователей с этим именем.
Можно добавлять условия с HAVING:
SELECT name, COUNT(*) as count
FROM users
GROUP BY name
HAVING COUNT(*) > 1;
Вернёт только те имена, которые встречаются больше одного раза.
3. SELECT DISTINCT с WHERE
Получение уникальных значений с фильтрацией:
SELECT DISTINCT name FROM users WHERE age > 18;
Сначала фильтруются записи по условию, затем выбираются уникальные значения.
4. UNION
Можно использовать UNION для получения уникальных значений из нескольких запросов:
SELECT name FROM users
UNION
SELECT name FROM archived_users;
UNION автоматически удаляет дубликаты. Для сохранения дубликатов используй UNION ALL:
SELECT name FROM users
UNION ALL
SELECT name FROM archived_users;
5. IN с подзапросом
Получение данных на основе уникальных значений:
SELECT * FROM users
WHERE id IN (SELECT DISTINCT user_id FROM orders);
Вернёт всех пользователей, у которых есть хотя бы один заказ.
6. Использование CTE (Common Table Expression)
Для сложных случаев с уникальными значениями:
WITH unique_names AS (
SELECT DISTINCT name FROM users
)
SELECT name FROM unique_names ORDER BY name;
7. ROW_NUMBER с партиционированием
Для более продвинутых случаев, когда нужно отфильтровать дубликаты, оставляя первый или последний:
WITH ranked_users AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY name ORDER BY created_at) as rn
FROM users
)
SELECT * FROM ranked_users WHERE rn = 1;
Вернёт первого пользователя с каждым уникальным именем (отсортировано по дате создания).
8. Сравнение производительности
| Метод | Производительность | Когда использовать |
|---|---|---|
| DISTINCT | Высокая | Простая выборка уникальных значений |
| GROUP BY | Высокая | Нужны агрегирующие функции |
| UNION | Средняя | Объединение результатов из разных таблиц |
| ROW_NUMBER | Средняя | Сложная фильтрация дубликатов |
Примеры с Java/Spring
В приложении на Spring Data JPA:
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// DISTINCT в методе query
@Query("SELECT DISTINCT u.name FROM User u")
List<String> findDistinctNames();
// С пагинацией и сортировкой
@Query("SELECT DISTINCT u.name FROM User u ORDER BY u.name")
Page<String> findDistinctNamesPageable(Pageable pageable);
}
Или используя нативный SQL:
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
@Query(value = "SELECT DISTINCT name FROM users ORDER BY name",
nativeQuery = true)
List<String> findUniqueNames();
}
Рекомендации
- Для простых случаев — используй DISTINCT, он оптимизирован в современных БД
- Если нужны агрегирующие функции — используй GROUP BY
- Для больших таблиц — добавляй индексы на столбцы в DISTINCT/GROUP BY
- Для сложной логики — используй CTE или оконные функции
- Всегда проверяй план запроса (EXPLAIN) при работе с большими объёмами данных