DISTINCT SQL — 100 универсальных примеров от простого к сложному

🟢 DISTINCT SQL. Введение

DISTINCT — ключевое слово SQL для выборки уникальных значений. distinct sql — способ убрать дубликаты строк, посчитать уникальные сущности и нормализовать результаты отчётов. В этой статье приведены 100 примеров применения DISTINCT от базовых выборок до сложных конструкций с JOIN, подзапросами, условными выражениями CASE и комбинациями с агрегатами (COUNT, SUM, AVG, MIN, MAX). Все примеры универсальны: используется стандартный синтаксис SQL без диалектных расширений.

Синтаксис

SELECT DISTINCT колонка1, колонка2
FROM   таблица;

Типовая конструкция

SELECT
    DISTINCT c.country, c.city
FROM
    customers AS c
WHERE
    c.is_active = 1
ORDER BY
    c.country, c.city;

Базовые выборки уникальных значений

Уникальные города клиентов с SELECT и фильтром активности в WHERE:

SELECT
    DISTINCT c.city
FROM
    customers AS c
WHERE
    c.is_active = 1
ORDER BY
    c.city;

Единый список категорий товаров через SELECT:

SELECT
    DISTINCT p.category
FROM
    products AS p
ORDER BY
    p.category;

Разные страны поставщиков с сортировкой через ORDER BY:

SELECT
    DISTINCT s.country
FROM
    suppliers AS s
ORDER BY
    s.country;

Перечень доступных валют счетов:

SELECT
    DISTINCT a.currency
FROM
    accounts AS a
ORDER BY
    a.currency;

Справочник должностей из таблицы сотрудников:

SELECT
    DISTINCT e.job_title
FROM
    employees AS e
ORDER BY
    e.job_title;

Список жанров фильмов для фильтра:

SELECT
    DISTINCT f.genre
FROM
    films AS f
ORDER BY
    f.genre;

Единый набор меток постов блога:

SELECT
    DISTINCT t.tag
FROM
    post_tags AS t
ORDER BY
    t.tag;

Коды регионов из адресов клиентов:

SELECT
    DISTINCT a.region_code
FROM
    addresses AS a
ORDER BY
    a.region_code;

Типы операций в журнале транзакций:

SELECT
    DISTINCT tx.kind
FROM
    transactions AS tx
ORDER BY
    tx.kind;

Список моделей устройств для витрины:

SELECT
    DISTINCT d.model
FROM
    devices AS d
ORDER BY
    d.model;

Набор учебных предметов из оценок студентов:

SELECT
    DISTINCT r.subject
FROM
    results AS r
ORDER BY
    r.subject;

Справочник складов по наименованию:

SELECT
    DISTINCT w.name
FROM
    warehouses AS w
ORDER BY
    w.name;

Фильтрация через WHERE перед выборкой уникальных

только активные товары:

SELECT
    DISTINCT p.brand
FROM
    products p
WHERE
    p.is_active = 1
ORDER BY
    p.brand;

транзакции за 2024 год:

SELECT
    DISTINCT tx.currency
FROM
    transactions tx
WHERE
    tx.tx_date >= DATE '2024-01-01' AND tx.tx_date < DATE '2025-01-01'
ORDER BY
    tx.currency;

Уникальные значения — студенты очной формы:

SELECT
    DISTINCT s.city
FROM
    students s
WHERE
    s.form = 'FULLTIME'
ORDER BY
    s.city;

заказы со статусом PAID

SELECT
    DISTINCT o.payment_method
FROM
    orders o
WHERE
    o.status = 'PAID'
ORDER BY
    o.payment_method;

комментарии без спама:

SELECT
    DISTINCT c.author
FROM
    comments c
WHERE
    c.is_spam = 0
ORDER BY
    c.author;

устройства в работе:

SELECT
    DISTINCT d.model
FROM
    devices d
WHERE
    d.state = 'OK'
ORDER BY
    d.model;

пациенты старше 18:

SELECT
    DISTINCT pt.city
FROM
    patients pt
WHERE
    pt.age >= 18
ORDER BY
    pt.city;

рейсы международные:

SELECT
    DISTINCT f.airline
FROM
    flights f
WHERE
    f.is_international = 1
ORDER BY
    f.airline;

магазины с витриной онлайн:

SELECT
    DISTINCT st.city
FROM
    stores st
WHERE
    st.has_online = 1
ORDER BY
    st.city;

кандидаты с опытом более 3 лет:

SELECT
    DISTINCT cand.primary_skill
FROM
    candidates cand
WHERE
    cand.years_exp > 3
ORDER BY
    cand.primary_skill;

Уникальные комбинации нескольких колонок

пара город‑страна клиентов:

SELECT
    DISTINCT c.country, c.city
FROM
    customers c
ORDER BY
    c.country, c.city;

категория‑бренд товаров:

SELECT
    DISTINCT p.category, p.brand
FROM
    products p
ORDER BY
    p.category, p.brand;

автор‑тема постов:

SELECT
    DISTINCT p.author_id, p.topic
FROM
    posts p
ORDER BY
    p.author_id, p.topic;

факультет‑курс:

SELECT
    DISTINCT c.faculty_id, c.course_code
FROM
    courses c
ORDER BY
    c.faculty_id, c.course_code;

склад‑товар:

SELECT
    DISTINCT s.warehouse_id, s.product_id
FROM
    stock s
ORDER BY
    s.warehouse_id, s.product_id;

аккаунт‑валюта:

SELECT
    DISTINCT a.account_no, a.currency
FROM
    accounts a
ORDER BY
    a.account_no, a.currency;

поставщик‑страна:

SELECT
    DISTINCT s.name, s.country
FROM
    suppliers s
ORDER BY
    s.name, s.country;

рейс‑дата:

SELECT
    DISTINCT f.flight_no, f.flight_date
FROM
    flights f
ORDER BY
    f.flight_no, f.flight_date;

курс‑семестр:

SELECT
    DISTINCT sc.course_id, sc.semester
FROM
    schedule sc
ORDER BY
    sc.course_id, sc.semester;

клиника‑услуга:

SELECT
    DISTINCT s.clinic_id, s.service_code
FROM
    services s
ORDER BY
    s.clinic_id, s.service_code;

Подсчёт уникальных значений через COUNT(DISTINCT …)

Сколько городов у каждого клиента — сочетание GROUP BY:

SELECT
    c.customer_id,
    COUNT(DISTINCT a.city) AS cities_cnt
FROM
    customers AS c
    INNER JOIN addresses AS a
        ON a.customer_id = c.customer_id
GROUP BY
    c.customer_id
ORDER BY
    c.customer_id;

Количество уникальных товаров в заказе:

SELECT
    o.order_id,
    COUNT(DISTINCT oi.product_id) AS unique_items
FROM
    orders AS o
    INNER JOIN order_items AS oi
        ON oi.order_id = o.order_id
GROUP BY
    o.order_id;

Число авторов, комментировавших пост:

SELECT
    p.post_id,
    COUNT(DISTINCT c.author_id) AS commenters
FROM
    posts AS p
    LEFT JOIN comments AS c
        ON c.post_id = p.post_id
GROUP BY
    p.post_id;

Уникальные категории, в которых продаётся бренд:

SELECT
    p.brand,
    COUNT(DISTINCT p.category) AS cat_cnt
FROM
    products AS p
GROUP BY
    p.brand;

Количество уникальных пациентов врача:

SELECT
    v.doctor_id,
    COUNT(DISTINCT v.patient_id) AS unique_patients
FROM
    visits AS v
GROUP BY
    v.doctor_id;

Сколько валют использовал клиент в платежах:

SELECT
    p.customer_id,
    COUNT(DISTINCT p.currency) AS used_currencies
FROM
    payments AS p
GROUP BY
    p.customer_id;

Число стран, из которых приходили заказы:

SELECT
    o.store_id,
    COUNT(DISTINCT a.country) AS countries
FROM
    orders AS o
    INNER JOIN addresses AS a
        ON a.address_id = o.shipping_address_id
GROUP BY
    o.store_id;

Количество уникальных устройств пользователя:

SELECT
    l.user_id,
    COUNT(DISTINCT l.device_id) AS devices
FROM
    logins AS l
GROUP BY
    l.user_id;

Уникальные жанры, в которых снимался актёр:

SELECT
    a.actor_id,
    COUNT(DISTINCT f.genre) AS genres
FROM
    actors AS a
    INNER JOIN film_cast AS fc
        ON fc.actor_id = a.actor_id
    INNER JOIN films AS f
        ON f.film_id = fc.film_id
GROUP BY
    a.actor_id;

Количество уникальных услуг по полису:

SELECT
    cl.policy_id,
    COUNT(DISTINCT s.service_code) AS services
FROM
    claims AS cl
    INNER JOIN services AS s
        ON s.claim_id = cl.claim_id
GROUP BY
    cl.policy_id;

Получение уникальных записей после JOIN

Список городов доставок из заказов через INNER JOIN:

SELECT
    DISTINCT a.city
FROM
    orders AS o
    INNER JOIN addresses AS a
        ON a.address_id = o.shipping_address_id
ORDER BY
    a.city;

Единый реестр поставщиков, задействованных в продажах:

SELECT
    DISTINCT s.name
FROM
    order_items AS oi
    INNER JOIN products AS p
        ON p.product_id = oi.product_id
    INNER JOIN suppliers AS s
        ON s.supplier_id = p.supplier_id
ORDER BY
    s.name;

Почты пользователей, оставлявших отзывы — без дублей:

SELECT
    DISTINCT u.email
FROM
    reviews AS r
    INNER JOIN users AS u
        ON u.user_id = r.user_id
ORDER BY
    u.email;

Справочник курсов, на которые записывались студенты:

SELECT
    DISTINCT c.course_code
FROM
    enrollments AS e
    INNER JOIN courses AS c
        ON c.course_id = e.course_id
ORDER BY
    c.course_code;

Города клиник, где проходили визиты:

SELECT
    DISTINCT cl.city
FROM
    visits AS v
    INNER JOIN clinics AS cl
        ON cl.clinic_id = v.clinic_id
ORDER BY
    cl.city;

Марки автомобилей, встречающихся в заказах на доставку:

SELECT
    DISTINCT car.brand
FROM
    deliveries AS d
    INNER JOIN cars AS car
        ON car.car_id = d.car_id
ORDER BY
    car.brand;

Контакты менеджеров, фигурирующих в сделках:

SELECT
    DISTINCT u.phone
FROM
    deals AS d
    INNER JOIN users AS u
        ON u.user_id = d.owner_id
ORDER BY
    u.phone;

Перечень складов, откуда отгружались товары:

SELECT
    DISTINCT w.name
FROM
    shipments AS sh
    INNER JOIN warehouses AS w
        ON w.warehouse_id = sh.warehouse_id
ORDER BY
    w.name;

Коды маршрутов, на которых были рейсы:

SELECT
    DISTINCT r.route_code
FROM
    flights AS f
    INNER JOIN routes AS r
        ON r.route_id = f.route_id
ORDER BY
    r.route_code;

Список страховых планов, по которым были выплаты:

SELECT
    DISTINCT pl.plan_code
FROM
    payouts AS po
    INNER JOIN policies AS pl
        ON pl.policy_id = po.policy_id
ORDER BY
    pl.plan_code;

Уникальные комбинации клиент‑валюта из платежей:

SELECT
    DISTINCT p.customer_id, p.currency
FROM
    payments AS p
ORDER BY
    p.customer_id, p.currency;

Уникальные пары магазин‑категория из продаж:

SELECT
    DISTINCT s.store_id, p.category
FROM
    order_items AS oi
    INNER JOIN products AS p
        ON p.product_id = oi.product_id
    INNER JOIN orders AS o
        ON o.order_id = oi.order_id
    INNER JOIN stores AS s
        ON s.store_id = o.store_id
ORDER BY
    s.store_id, p.category;

Пользователи, встречающиеся в логах авторизации:

SELECT
    DISTINCT u.user_id
FROM
    logins AS l
    INNER JOIN users AS u
        ON u.user_id = l.user_id
ORDER BY
    u.user_id;

Города, из которых делали возвраты товаров:

SELECT
    DISTINCT a.city
FROM
    returns AS r
    INNER JOIN orders AS o
        ON o.order_id = r.order_id
    INNER JOIN addresses AS a
        ON a.address_id = o.shipping_address_id
ORDER BY
    a.city;

Выделение уникальных значений в подзапросах

Фильтрация клиентов, делавших заказы в разных странах:

SELECT
    c.customer_id,
    c.full_name
FROM
    customers AS c
WHERE
    c.customer_id IN (
        SELECT
            o.customer_id
        FROM
            orders AS o
            INNER JOIN addresses AS a
                ON a.address_id = o.shipping_address_id
        GROUP BY
            o.customer_id
        HAVING
            COUNT(DISTINCT a.country) >= 2
    );

Список курсов с участием студентов из разных городов:

SELECT
    c.course_id,
    c.title
FROM
    courses AS c
WHERE
    c.course_id IN (
        SELECT
            e.course_id
        FROM
            enrollments AS e
            INNER JOIN students AS s
                ON s.student_id = e.student_id
        GROUP BY
            e.course_id
        HAVING
            COUNT(DISTINCT s.city) > 3
    );

Магазины, где продавались товары из 5 и более брендов:

SELECT
    st.store_id,
    st.name
FROM
    stores AS st
WHERE
    st.store_id IN (
        SELECT
            o.store_id
        FROM
            orders AS o
            INNER JOIN order_items AS oi
                ON oi.order_id = o.order_id
            INNER JOIN products AS p
                ON p.product_id = oi.product_id
        GROUP BY
            o.store_id
        HAVING
            COUNT(DISTINCT p.brand) >= 5
    );

Врачи, у которых были пациенты из ≥ 4 клиник:

SELECT
    d.doctor_id,
    d.full_name
FROM
    doctors AS d
WHERE
    d.doctor_id IN (
        SELECT
            v.doctor_id
        FROM
            visits AS v
        GROUP BY
            v.doctor_id
        HAVING
            COUNT(DISTINCT v.clinic_id) >= 4
    );

Преподаватели, ведущие в двух и более факультетах:

SELECT
    t.teacher_id,
    t.teacher_name
FROM
    teachers AS t
WHERE
    t.teacher_id IN (
        SELECT
            ct.teacher_id
        FROM
            course_teachers AS ct
            INNER JOIN courses AS c
                ON c.course_id = ct.course_id
        GROUP BY
            ct.teacher_id
        HAVING
            COUNT(DISTINCT c.faculty_id) >= 2
    );

Пассажиры с билетами более чем на 3 авиакомпании:

SELECT
    p.passenger_id,
    p.full_name
FROM
    passengers AS p
WHERE
    p.passenger_id IN (
        SELECT
            t.passenger_id
        FROM
            tickets AS t
        GROUP BY
            t.passenger_id
        HAVING
            COUNT(DISTINCT t.airline) > 3
    );

Клиенты, оплатившие разными способами:

SELECT
    c.customer_id,
    c.full_name
FROM
    customers AS c
WHERE
    c.customer_id IN (
        SELECT
            o.customer_id
        FROM
            orders AS o
        GROUP BY
            o.customer_id
        HAVING
            COUNT(DISTINCT o.payment_method) >= 2
    );

Пользователи, заходившие с ≥ 3 устройств:

SELECT
    u.user_id,
    u.email
FROM
    users AS u
WHERE
    u.user_id IN (
        SELECT
            l.user_id
        FROM
            logins AS l
        GROUP BY
            l.user_id
        HAVING
            COUNT(DISTINCT l.device_id) >= 3
    );

Проекты с исполнителями из разных отделов:

SELECT
    p.project_id,
    p.title
FROM
    projects AS p
WHERE
    p.project_id IN (
        SELECT
            a.project_id
        FROM
            assignments AS a
            INNER JOIN employees AS e
                ON e.emp_id = a.emp_id
        GROUP BY
            a.project_id
        HAVING
            COUNT(DISTINCT e.dept_id) >= 2
    );

Полисы, по которым обращались из нескольких клиник:

SELECT
    pl.policy_id,
    pl.plan_code
FROM
    policies AS pl
WHERE
    pl.policy_id IN (
        SELECT
            cl.policy_id
        FROM
            claims AS cl
        GROUP BY
            cl.policy_id
        HAVING
            COUNT(DISTINCT cl.clinic_id) >= 2
    );

Роуты, по которым летали в разные месяцы:

SELECT
    r.route_id,
    r.route_code
FROM
    routes AS r
WHERE
    r.route_id IN (
        SELECT
            f.route_id
        FROM
            flights AS f
        GROUP BY
            f.route_id
        HAVING
            COUNT(DISTINCT f.flight_month) >= 2
    );

Аккаунты с транзакциями в нескольких валютах:

SELECT
    a.account_no
FROM
    accounts AS a
WHERE
    a.account_no IN (
        SELECT
            t.account_no
        FROM
            transactions AS t
        GROUP BY
            t.account_no
        HAVING
            COUNT(DISTINCT t.currency) >= 2
    );

Условные выборки с CASE и DISTINCT

Уникальные категории среди активных товаров — переключение через CASE:

SELECT
    DISTINCT CASE WHEN p.is_active = 1 THEN p.category ELSE NULL END AS category_active
FROM
    products AS p
WHERE
    p.is_active = 1;

Пользовательские роли без дублей с нормализацией заглавных букв:

SELECT
    DISTINCT CASE WHEN r.role IS NULL THEN 'UNKNOWN' ELSE r.role END AS role_norm
FROM
    user_roles AS r;

Номер недели из дат заказов — уникальные значения:

SELECT
    DISTINCT CASE WHEN o.order_week IS NULL THEN 0 ELSE o.order_week END AS order_week
FROM
    orders AS o;

Уникальные статусы платежей с подстановкой значения по умолчанию:

SELECT
    DISTINCT CASE WHEN p.status IS NULL THEN 'N/A' ELSE p.status END AS status_norm
FROM
    payments AS p;

Сбор уникальных сегментов лояльности клиентов:

SELECT
    DISTINCT CASE WHEN c.loyalty_tier = '' THEN 'NONE' ELSE c.loyalty_tier END AS tier_norm
FROM
    customers AS c;

Стандартизация формата номера телефона и выбор уникальных:

SELECT
    DISTINCT CASE WHEN u.phone LIKE '+%' THEN u.phone ELSE u.phone END AS phone_norm
FROM
    users AS u;

Выбор уникальных каналов продаж по условию:

SELECT
    DISTINCT CASE WHEN s.channel IN ('ONLINE','OFFLINE') THEN s.channel ELSE 'OTHER' END AS ch
FROM
    sales AS s;

Уникальные уровни срочности задач, включая пустые как ‘NONE’:

SELECT
    DISTINCT CASE WHEN t.priority IS NULL THEN 'NONE' ELSE t.priority END AS priority_norm
FROM
    tasks AS t;

Сопоставление с UNION и UNION ALL

Единый словарь городов из клиентов и поставщиков через UNION:

SELECT DISTINCT city FROM customers
UNION
SELECT DISTINCT city FROM suppliers;

Агрегация уникальных валют из счетов и транзакций с UNION:

SELECT DISTINCT currency FROM accounts
UNION
SELECT DISTINCT currency FROM transactions;

Список ролей из пользователей и системных ролей:

SELECT DISTINCT role FROM user_roles
UNION
SELECT DISTINCT role FROM system_roles;

Общие коды регионов из адресов и складов:

SELECT DISTINCT region_code FROM addresses
UNION
SELECT DISTINCT region_code FROM warehouses;

Набор статусов из заказов и доставок:

SELECT DISTINCT status FROM orders
UNION
SELECT DISTINCT status FROM deliveries;

Соединение уникальных жанров из фильмов и сериалов:

SELECT DISTINCT genre FROM films
UNION
SELECT DISTINCT genre FROM series;

Сортировка уникальных наборов через ORDER BY

Категории по алфавиту:

SELECT
    DISTINCT p.category
FROM
    products p
ORDER BY
    p.category;

Города по алфавиту:

SELECT
    DISTINCT a.city
FROM
    addresses a
ORDER BY
    a.city;

Курсы по коду:

SELECT
    DISTINCT c.course_code
FROM
    courses c
ORDER BY
    c.course_code;

Сортировка уникальных значений — планы по коду:

SELECT
    DISTINCT pl.plan_code
FROM
    policies pl
ORDER BY
    pl.plan_code;

Стабильная сортировка уникальных значений — роли по имени:

SELECT
    DISTINCT r.role
FROM
    user_roles r
ORDER BY
    r.role;

Отбор уникальных значений — жанры по названию:

SELECT
    DISTINCT f.genre
FROM
    films f
ORDER BY
    f.genre;

Прикладные сценарии из реальной практики

E‑commerce: список способов доставки без дублей:

SELECT
    DISTINCT o.shipping_method
FROM
    orders AS o
ORDER BY
    o.shipping_method;

Финансы: уникальные типы транзакций в отчёте по движению:

SELECT
    DISTINCT tx.kind
FROM
    transactions AS tx
ORDER BY
    tx.kind;

HR: список навыков кандидатов для фильтрации вакансий:

SELECT
    DISTINCT c.skill
FROM
    candidate_skills AS c
ORDER BY
    c.skill;

Образование: набор семестров, встречающихся в расписании:

SELECT
    DISTINCT sc.semester
FROM
    schedule AS sc
ORDER BY
    sc.semester;

Медицина: уникальные диагнозы из карточек пациентов:

SELECT
    DISTINCT pt.diagnosis_code
FROM
    patients AS pt
ORDER BY
    pt.diagnosis_code;

Логистика: маршруты отгрузок без повторов:

SELECT
    DISTINCT sh.route_code
FROM
    shipments AS sh
ORDER BY
    sh.route_code;

IoT: список моделей датчиков, поступающих в telemetry:

SELECT
    DISTINCT t.sensor_model
FROM
    telemetry AS t
ORDER BY
    t.sensor_model;

CRM: статусы сделок для настройки воронки:

SELECT
    DISTINCT d.status
FROM
    deals AS d
ORDER BY
    d.status;

Страхование: коды покрытий по полисам:

SELECT
    DISTINCT pl.coverage_code
FROM
    policies AS pl
ORDER BY
    pl.coverage_code;

Retail: наименования отделов магазинов без дублей:

SELECT
    DISTINCT s.dept_name
FROM
    store_departments AS s
ORDER BY
    s.dept_name;

Безопасность: перечень типов событий аудита:

SELECT
    DISTINCT a.event_type
FROM
    audit_log AS a
ORDER BY
    a.event_type;

Поддержка: тематики обращений клиентов:

SELECT
    DISTINCT t.topic
FROM
    tickets AS t
ORDER BY
    t.topic;

Заключение

distinct sql — это набор практик по работе с уникальностями: от простых справочников до сложных аналитических отчётов.Используйте DISTINCT для де‑дупликации результатов, COUNT(DISTINCT …) — для вычисления уникальных количеств, комбинируйте с JOIN, WHERE, GROUP BY, подзапросами и CASE. Держите код читабельным: выравнивайте ключевые слова, сортируйте результаты через ORDER BY и проверяйте планы выполнения для устойчивой производительности.


 

Понравилась статья? Поделиться с друзьями: