Запити
Оператор DISTINCT дозволяє вибрати унікальні дані щодо певних стовпців.
Наприклад, різні товари можуть мати тих самих виробників, і, припустимо, ми наступна таблиця товаров:
DROP TABLE IF EXISTS products; CREATE TABLE products ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, company TEXT NOT NULL, product_count INTEGER DEFAULT 0, price INTEGER ); INSERT INTO products (name, company, product_count, price) VALUES ('iPhone 13', 'Apple', 3, 76000), ('iPhone 12', 'Apple', 3, 51000), ('Galaxy S21', ' Samsung', 2, 56000), ('Galaxy S20', 'Samsung', 1, 41000), ('P40 Pro', 'Huawei', 5, 36000);
Виберемо всіх виробників:
SELECT company FROM products;
Але за такого запиту виробники повторюються. Тепер застосуємо оператор DISTINCT для вибірки унікальних значень:
SELECT DISTINCT company FROM products;
Також ми можемо задавати вибірку унікальних значень за кількома стовпцями:
SELECT DISTINCT company, product_count FROM products;
Тут для вибірки використовуються стовпці company та product_count. З п'яти рядків тільки для двох рядків ці стовпці мають значення, що повторюються. Тому у вибірці буде 4 рядки:
Варто зазначити, що SQLite розглядає значення NULL як повторювані. Тому якщо оператор DISTINCT здійснює унікальну вибірку по стовпцю, для якого в декількох рядках значиться значення NULL, то оператор DISTINCT відбере лише один рядок.
Запити
За допомогою оператора DISTINCT можна вибрати унікальні дані щодо певних стовпців.
Наприклад, різні товари можуть мати тих самих виробників, і, припустимо, ми наступна таблиця товаров:
USE productsdb; DROP TABLE IF EXISTS Products; CREATE TABLE Products ( Id INT AUTO_INCREMENT PRIMARY KEY, ProductName VARCHAR(30) NOT NULL, Manufacturer VARCHAR(20) NOT NULL, ProductCount INT DEFAULT 0, Price DECIMAL NOT NULL ); INSERT INTO Products (ProductName, Manufacturer, ProductCount, Price) VALUES ('iPhone X', 'Apple', 3, 71000), ('iPhone 8', 'Apple', 3, 56000), ('Galaxy S9', ' Samsung', 6, 56000), ('Galaxy S8', 'Samsung', 2, 46000), ('Honor 10', 'Huawei', 3, 26000);
Виберемо всіх виробників:
SELECT Manufacturer FROM Products;
Однак за такого запиту виробники повторюються. Тепер застосуємо оператор DISTINCT для вибірки унікальних значень:
SELECT DISTINCT Manufacturer FROM Products;
Також ми можемо задавати вибірку унікальних значень за кількома стовпцями:
SELECT DISTINCT Manufacturer, ProductCount FROM Products;
В даному випадку для вибірки використовуються стовпці Manufacturer та ProductCount. З п'яти рядків тільки для двох рядків ці стовпці мають значення, що повторюються. Тому у вибірці буде 4 рядки:
Вибір унікальних значень: оператор SELECT DISTINCT у SQL
SQL - це потужна та універсальна мова для роботи з даними. Однією з ключових його особливостей є можливість вибору унікальних значень за допомогою оператора SELECT DISTINCT. Ця функція дозволяє отримувати чисті та незахаращені дані для аналізу. Давайте детально розберемося, як використовувати DISTINCT для оптимізації SQL запитів.
Призначення та синтаксис оператора SELECT DISTINCT
Оператор SELECT DISTINCT призначений для повернення унікальних рядків з таблиці. Він прибирає записи, що дублюються, і залишає по одному рядку для кожного унікального значення або комбінації значень у вибраних стовпцях.
Синтаксис оператора SELECT DISTINCT у SQL виглядає так:
Після ключового слова DISTINCT указується список стовпців, за якими потрібно повернути унікальні значення. Якщо вказати simply DISTINCT без стовпців, то буде повернено унікальні рядки по всіх стовпцях таблиці.
Наприклад, щоб отримати список унікальних імен клієнтів із таблиці Customers, можна написати такий запит:
А для отримання всіх унікальних комбінацій імені та прізвища клієнтів:
Таким чином, оператор DISTINCT дозволяє легко отримувати чистий і унікальний набір даних для аналізу, видаляючи всі записи, що повторюються.
Відмінності DISTINCT від GROUP BY
Оператор DISTINCT часто плутають із GROUP BY у SQL. Хоча обидва дозволяють отримати унікальні значення, між ними є важливі відмінності:
- DISTINCT повертає всі унікальні рядки, а GROUP BY групує їх та повертає по одному запису на кожну групу
- GROUP BY також дозволяє застосовувати агрегатні функції до груп, наприклад, COUNT(), SUM() тощо.
- GROUP BY може групувати стовпці, які не включені у вибірку, на відміну від DISTINCT
Використання DISTINCT є доречним, коли потрібно просто отримати всі унікальні значення одного або декількох стовпців. GROUP BY краще, якщо потрібно здійснити групування та агрегацію даних.
Наприклад, щоб порахувати кількість унікальних імен клієнтів з DISTINCT можна написати так:
Обидва запити повернуть однаковий результат, але другий підхід дає більшу гнучкість для подальшої обробки даних.
Використання DISTINCT з об'єднанням таблиць
При об'єднанні даних із кількох таблиць оператор DISTINCT також може бути корисним для отримання унікальних значень. Однак тут є одна тонкість.
Розглянемо запит із LEFT JOIN, що поєднує таблиці Клієнти та Замовлення:
SELECT DISTINCT CustomerName, OrderAmount FROM Customers LEFT JOIN Orders ON Customers.id = Orders.customer_id;
Тут у результат попадуть унікальні пари значень CustomerName і OrderAmount.
Щоб отримати по-справжньому унікальний список імен клієнтів без повторів, потрібно застосувати DISTINCT до стовпця лише з лівої таблиці:
SELECT DISTINCT Customers.Name FROM Customers LEFT JOIN Orders ON Customers.id = Orders.customer_id;
Таким чином, при використанні DISTINCT із з'єднаннями таблиць потрібно явно вказувати стовпці однієї таблиці, за якими потрібні унікальні значення.
Вибір стовпців для SELECT DISTINCT
Від того, які стовпці вказати після DISTINCT, може залежати кінцевий результат запиту.
Нехай є таблиця Покупки з колонками Дата, Клієнт, Товар та Кількість.
Але якщо додати в SELECT ще один стовпець, наприклад, Товар:
Результат буде містити всі унікальні комбінації значень стовпців Дата і Товар.
Тому при використанні DISTINCT дуже важливо включати в запит тільки ті стовпці, які дійсно потрібні для отримання унікальних даних.
У деяких СУБД є розширений синтаксис DISTINCT ON, який дозволяє явно вказати стовпці для унікалізації. Наприклад, у PostgreSQL запит буде виглядати так:
Це поверне очікуваний результат з унікальними датами, ігноруючи стовпець Товар.
Альтернативи оператору SELECT DISTINCT
Хоча DISTINCT - простий спосіб отримати унікальні дані, існують інші підходи для дедуплікації результатів запиту чи таблиці.
- Фільтрування дублікатів на стороні клієнта Можна отримати всі дані без DISTINCT, а потім відфільтрувати повтори програмно, наприклад, Python або Java.
- Використання агрегатних функцій на кшталт COUNT(DISTINCT . ) та GROUP BY для групування унікальних значень.
- Застосування UNION замість UNION ALL при об'єднанні запитів, щоб виключити рядки, що дублюються.
- Дедуплікація даних одразу при INSERT за допомогою унікальних індексів або обмежень.
У кожного підходу є свої плюси та мінуси. Наприклад, фільтрація дублікатів на стороні програми може знизити навантаження на БД.
В цілому, DISTINCT - простий і зрозумілий спосіб для унікалізації даних на рівні SQL-запиту.
Оптимізація продуктивності запитів із DISTINCT
Використання SELECT DISTINCT може негативно позначитися на продуктивності запиту, якщо не вжити заходів щодо оптимізації. Розглянемо основні способи прискорення DISTINCT:
- Створення індексів по шпальтах, що використовуються в DISTINCT. Це дозволить БД швидше знаходити унікальні значення.
- Застосування попередньої фільтрації даних за допомогою умов WHERE Це дозволить DISTINCT працювати з меншим обсягом даних.
- Включення в запит лише необхідних стовпців, якими вибираються унікальні рядки.
- Використання агрегатних функцій замість DISTINCT, коли це можливо. Наприклад, COUNT(DISTINCT) замість просто DISTINCT.
- Перенесення дедуплікації на бік клієнта, якщо це прийнятно за вимогами до актуальності та продуктивності.
Також варто звертати увагу на особливості оптимізації DISTINCT у конкретній СУБД. Наприклад, у Oracle є параметр OPTIMIZER_DISTINCT_AGGREGATION, який може допомогти у деяких випадках.
Грамотне застосування цих прийомів дозволить значно прискорити обробку запитів із DISTINCT та знизити навантаження на БД.
Інструменти та бібліотеки для роботи з DISTINCT
Для спрощення використання SELECT DISTINCT у прикладному коді існує безліч бібліотек та інструментів.
- Бібліотека pandas Python має метод drop_duplicates() для видалення дублікатів в DataFrame.
- distinct() Scala дозволяє ефективно отримувати унікальні дані з колекцій.
- Для роботи з БД Java зручна бібліотека jOOQ з підтримкою DISTINCT.
- У PL/SQL Developer є інструмент генерації DISTINCT-запитів до таблиці без написання коду.
- HeidiSQL дозволяє візуально будувати запити із DISTINCT через зручний GUI.
Багато СУБД також мають вбудовані засоби профілювання та оптимізації запитів із DISTINCT. Їх варто вивчити для більш ефективного використання цього оператора.
Вибір конкретних бібліотек та інструментів залежить від стеку технологій, особливостей інфраструктури та поставлених завдань.