Новини високих технологій
» » SQL distinct: опис, приклади, властивості

SQL distinct: опис, приклади, властивості

2-05-2017, 21:00
1 302
Найчастіше при використанні SQL для вибірки інформації з таблиць, користувач отримує надлишкові дані, які полягають в наявності абсолютно ідентичних повторюваних рядків. Для виключення цієї ситуації використовується аргумент SQL distinct в реченні Select. У даній статті будуть розглянуті приклади використання даного аргументу, а також ситуації, в яких від застосування аргументу краще відмовитися. Перш ніж ми приступимо до розгляду конкретних прикладів, створимо в базі даних пару необхідних таблиць.
SQL distinct: опис, приклади, властивості

Підготовка таблиць

Уявімо, що у нас у базі даних зберігається інформація про шпалерах, представлена у двох таблицях. Це таблиця Oboi (шпалери) з полями: id (унікальний ідентифікатор), type (тип шпалер – паперові, вінілові та ін), color (колір), struct (структура) і ргісе (ціна). Таблиця Ostatki (залишки) з полями id_oboi (посилання на унікальний ідентифікатор таблиці Oboi) та count (кількість рулонів на складі).


Заповнимо таблиці даними. У таблицю із шпалерами додамо 9 записів:

Oboi



id



type



color



struct



price



1



Паперові



Мультиколор



Тиснені



569



2



Паперові двошарові



Беж



Гладка



1148



3



Вінілові



Оранж



Тиснені



504



4



Флізелінові



Беж



Тиснені



10209



5



Паперові двошарові



Беж



Гладка



1506



6



Паперові



Мультиколор



Гладка



954



7



Вінілові



Коричневі



Гладка



372



8



Флізелінові



Білі



Тиснені



9801



9



Тканинні



Рожеві



Гладка



11665

У таблицю із залишками – також дев'ять записів:

Ostatki



id_oboi



count



1



8



2



12



3



24



4



9



5



16



6



7



7



24



8



32



9



11

Приступимо до опису порядку використання distinct в SQL.

Місце в реченні Select distinct

Аргумент distinct слід поміщати відразу після ключового слова Select запиту. Він застосовується до всіх стовпців, вказаними в пропозиції Select, тому що буде виключати з підсумкового результату запиту абсолютно ідентичні рядка. Таким чином, достатньо один раз вказати при написанні SQL-запиту «select distinct». Виняток становить використання distinct всередині агрегатних функцій, що розглянемо трохи пізніше.



Слід пам'ятати, що більшість СУБД і не розпізнає ваш запит виду:

SELECT distinct Ostatki.Count, distinct Oboi.* FROM Oboi INNER JOIN Ostatki ON Oboi.id = Ostatki.id_oboi

Тут кілька разів розглянутий зазначений аргумент або вказаний один раз, але перед другим, третім або іншим выбираемым стовпцем. Ви отримаєте помилку з посиланням на неточності в синтаксисі.

Застосування distinct в стандартних запитах

Очевидно, що при грамотному побудові структури таблиць і їх заповненні, всередині однієї таблиці виключені ситуації, коли зустрічаються абсолютно ідентичні рядка. Тому виконання запиту «Select distinct *» з вибіркою з однієї таблиці практично недоцільно.
Уявімо ситуацію, коли нам необхідно дізнатися, якого типу є у нас шпалери, відразу для зручності виконаємо сортування за типом:

SELECT Oboi.type FROM Oboi order by type

І отримаємо результат:

type



Паперові



Паперові



Паперові двошарові



Паперові двошарові



Вінілові



Вінілові



Тканинні



Флізелінові



Флізелінові

Як бачимо, у таблиці присутні повторювані рядки. Якщо ж ми додамо в пропозицію Select distinct:

SELECT distinct Oboi.type FROM Oboi order by type

то отримаємо результат без повторів:

type



Паперові



Паперові двошарові



Вінілові



Тканинні



Флізелінові

Таким чином, якщо грамотно вносилися дані в таблиці, то відразу по дзвінку або запитом покупців ми зможемо відповісти, що рідких шпалер, стеклообоев і акрилових шпалер в наявності в магазині немає. Враховуючи, що асортимент у магазинах зазвичай не обмежується однією сотнею шпалер, переглянути перелік з неуникальних типів було б досить трудомістке.

Застосування distinct всередині агрегатних функцій

Аргумент SQL distinct можна використовувати з будь-агрегатної функцією. Але для Min і Max його застосування не дасть ніякого ефекту, а при обчисленні суми або середнього значення рідко можна уявити ситуацію, коли не потрібно було б враховувати повтори. Припустимо, ми хочемо дізнатися, наскільки заповнений наш склад, і для цього відправляємо запит, який обчислює загальну кількість рулонів на складі:

SELECT sum(Ostatki.count) FROM Ostatki

Запит видасть відповідь 143. Якщо ж ми змінимо на:

SELECT sum(distinct Ostatki.count) FROM Ostatki

то отримаємо всього 119 адже шпалери під артикулами 3 і 7 знаходяться на складі в однаковій кількості. Однак очевидно, що ця відповідь невірний. Найчастіше в SQL distinct застосовується з функцією Count. Так, без праці ми можемо дізнатися, скільки унікальних видів шпалер у нас взагалі є:

SELECT count(distinct Oboi.type) FROM Oboi

І отримати результат 5 – звичайні паперові двошарові, вінілові, тканинні і бамбукові. Напевно всі бачили рекламу типу: «Тільки у нас більше 20 видів різних шпалер!», під якої мається на увазі, що в даному магазині не пара десятків рулонів, а шпалери найрізноманітніших сучасних типів. Цікаво, що у одному запиті можна зазначати декілька функцій Count як з атрибутом distinct, так і без нього. Тобто це єдина ситуація, коли distinct в Select'е може бути кілька разів.

Коли слід відмовитися від застосування аргументу

Від застосування аргументу SQL distinct слід відмовитися в одному з двох випадків: Ви виконуєте вибірку з таблиць і впевнені в унікальності значень у кожній. У такому разі застосування аргументу недоцільно, адже це додаткове навантаження на сервер або клієнта (залежно від виду СУБД). Ви боїтеся втратити потрібні дані. Пояснимо. Припустимо, начальник просить вас вивести список шпалер, які у вас є, з зазначенням двох стовпців – тип і колір. За звичкою ви вказуєте аргумент distinct:


SELECT distinct Oboi.type, Oboi.color FROM Oboi ORDER BY Oboi.type

І – втрачаєте частину даних:

type



color



Паперові



Мультиколор



Паперові двошарові



Беж



Вінілові



Коричневі



Вінілові



Оранж



Тканинні



Рожеві



Флізелінові



Беж



Флізелінові



Білі

Може скластися враження, що паперових шпалер (звичайних і двошарових) у нас всього по одному виду, хоча насправді навіть в нашій маленькій таблиці їх по два артикула (результат без distinct):

type



color



Паперові



Мультиколор



Паперові



Мультиколор



Паперові двошарові



Беж



Паперові двошарові



Беж



Вінілові



Коричневі



Вінілові



Оранж



Тканинні



Рожеві



Флізелінові



Білі



Флізелінові



Беж

Тому, як і при написанні будь-якого запиту, з аргументом distinct треба бути акуратним і грамотно вирішувати питання з її застосуванням в залежності від поставленої задачі.

Альтернатива distinct

Протилежність аргументу distinct – аргумент All. При його застосуванні повторювані рядки зберігаються. Але оскільки за замовчуванням СУБД так і вважає, що потрібно виводити всі значення, то аргумент All – це скоріше уточнитель, ніж реальний функціональний аргумент.
Сподіваємося, що наше тепер зрозуміло, коли застосовується distinct (SQL). Опис дало вам повну інформацію про доцільність застосування цього аргументу при вирішенні різних завдань. Адже, як виявилося, навіть такий простий аргумент у своєму застосуванні приховує цілком відчутну ймовірність втратити деякі дані і вивести неточну інформацію.
Цікаво по темі
Оператор Select (SQL)
Оператор Select (SQL)
У статті описується оператор Select мови SQL. Будуть представлені інструкції, як витягти інформацію з таблиць, як уточнити вибір, а також як
Оператор SQL INNER JOIN: приклади, синтаксис і особливості
Оператор SQL INNER JOIN: приклади, синтаксис і особливості
Розробка будь-якої бази даних передбачає не тільки створення і наповнення таблиць різноманітною інформацією, але і подальшу роботу з даними. Для
SQL Where: способи застосування та приклади
SQL Where: способи застосування та приклади
Для вибору даних з бази використовується конструкція Select[набор данних]from[имя таблици]. Як показує досвід, в 80 % випадків використання запитів
HAVING SQL: опис, синтаксис, приклади
HAVING SQL: опис, синтаксис, приклади
Серед інших параметрів оператора SELECT мови SQL параметр HAVING є вкрай корисним. Це стосується тих випадків, коли результуючу вибірку потрібно не
MySQL - запит у запиті. MySQL: приклади запитів. Вкладені запити MySQL
MySQL - запит у запиті. MySQL: приклади запитів. Вкладені запити MySQL
Основні особливості вкладених запитів. Як побудувати в MySQL запит в запиті. Для чого необхідні вкладені запити. Приклад вкладеного запиту MySQL.
MySQL select select from: оператор вибірки
MySQL select select from: оператор вибірки
MySQL - одна з найпопулярніших систем управління базами даних (СУБД). У даній статті ми розглянемо базову функціональність оператора вибірки SELECT,