Запросы
С помощью оператора 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 строки:
Как выбрать уникальные значения не используя distinct?
может быть используя подзапрос, группировку строк и оконную функцию.
не уверен, что код сработает, но как-то так:
select * from ( SELECT dp.id_dep, dep.code_department, dp.code_place, vc.valuename, vr.valueseria, vr.nominal, vr.bаlrate, vr.dt_open, FROM valuerests vr JOIN valuecodes vc ON vr.id_value = vc.id_value JOIN valuekinds vk ON vc.id_valkind = vk.id_valkind JOIN place dp ON vr.id_place = dp.id_place JOIN department dep ON dp.id_dep = dep.id_department WHERE vk.code = 'AAA' AND vr.balrate > 0 AND vr.dt_open = :p_dt AND dp.code_place = :p_cp ) where ROW_NUMBER() OVER(PARTITION BY id_dep, code_department, code_place, valuename,valueseria,nominal,bаlrate, dt_open ORDER BY balrate DESC) = 1
суть в том, чтобы дать номера строкам в группировке и брать только те, где 1(то есть не повторяющиеся)
чтобы его запустить надо поэксперементировать, надеюсь идея окажется полезной 🙂
select tbl.*, ROW_NUMBER() OVER(PARTITION BY id_dep, code_department, code_place, valuename,valueseria,nominal,bаlrate, dt_open ORDER BY balrate DESC) as ic from ( SELECT dp.id_dep, dep.code_department, dp.code_place, vc.valuename, vr.valueseria, vr.nominal, vr.bаlrate, vr.dt_open, FROM valuerests vr JOIN valuecodes vc ON vr.id_value = vc.id_value JOIN valuekinds vk ON vc.id_valkind = vk.id_valkind JOIN place dp ON vr.id_place = dp.id_place JOIN department dep ON dp.id_dep = dep.id_department WHERE vk.code = 'AAA' AND vr.balrate > 0 AND vr.dt_open = :p_dt AND dp.code_place = :p_cp ) tbl where ic = 1
select * from ( select t.*, ROW_NUMBER() OVER(PARTITION BY c1,c2,c3,c4 order by c2 DESC) as Ic from ( select 'AA' as c1, 12 as c2, 33.5 as c3, 'BB' as c4 UNION ALL select 'AA' as c1, 12 as c2, 33.5 as c3, 'BB' as c4 UNION ALL select 'AA' as c1, 12 as c2, 33.5 as c3, 'BB' as c4 ) t )t2 where Ic = 1
Как в sql выбрать уникальные значения
С помощью DISTINCT можно получить только уникальные значения из столбца таблицы.
SELECT DISTINCT first_name FROM users; first_name ------------ Roman Sean Alex Michal Britney
Кроме того, DISTINCT можно использовать и с несколькими полями сразу:
SELECT DISTINCT first_name, last_name FROM users; first_name | last_name ------------+--------------- Bruce | Williss Sean | Connery Robin | Williams
Секция DISTINCT
Если указан SELECT DISTINCT , то в результате запроса останутся только уникальные строки. Таким образом, из всех наборов полностью совпадающих строк в результате останется только одна строка.
Вы можете указать столбцы, по которым хотите отбирать уникальные значения: SELECT DISTINCT ON (column1, column2. ) . Если столбцы не указаны, то отбираются строки, в которых значения уникальны во всех столбцах.
┌─a─┬─b─┬─c─┐ │ 1 │ 1 │ 1 │ │ 1 │ 1 │ 1 │ │ 2 │ 2 │ 2 │ │ 2 │ 2 │ 2 │ │ 1 │ 1 │ 2 │ │ 1 │ 2 │ 2 │ └───┴───┴───┘
Использование DISTINCT без указания столбцов:
SELECT DISTINCT * FROM t1;
┌─a─┬─b─┬─c─┐ │ 1 │ 1 │ 1 │ │ 2 │ 2 │ 2 │ │ 1 │ 1 │ 2 │ │ 1 │ 2 │ 2 │ └───┴───┴───┘
Использование DISTINCT с указанием столбцов:
SELECT DISTINCT ON (a,b) * FROM t1;
┌─a─┬─b─┬─c─┐ │ 1 │ 1 │ 1 │ │ 2 │ 2 │ 2 │ │ 1 │ 2 │ 2 │ └───┴───┴───┘
DISTINCT и ORDER BY
ClickHouse поддерживает использование секций DISTINCT и ORDER BY для разных столбцов в одном запросе. Секция DISTINCT выполняется до секции ORDER BY .
Таблица для примера:
┌─a─┬─b─┐ │ 2 │ 1 │ │ 1 │ 2 │ │ 3 │ 3 │ │ 2 │ 4 │ └───┴───┘
При выборе данных с помощью SELECT DISTINCT a FROM t1 ORDER BY b ASC , мы получаем следующий результат:
┌─a─┐ │ 2 │ │ 1 │ │ 3 │ └───┘
Если мы изменим направление сортировки SELECT DISTINCT a FROM t1 ORDER BY b DESC , мы получаем следующий результат:
┌─a─┐ │ 3 │ │ 1 │ │ 2 │ └───┘
Ряд 2, 4 был разрезан перед сортировкой.
Учитывайте эту специфику при разработке запросов.
Обработка NULL
DISTINCT работает с NULL как-будто NULL — обычное значение и NULL==NULL . Другими словами, в результате DISTINCT , различные комбинации с NULL встретятся только один раз. Это отличается от обработки NULL в большинстве других контекстов.
Альтернативы
Можно получить такой же результат, применив GROUP BY для того же набора значений, которые указан в секции SELECT , без использования каких-либо агрегатных функций. Но есть несколько отличий от GROUP BY :
- DISTINCT может применяться вместе с GROUP BY .
- Когда секция ORDER BY опущена, а секция LIMIT присутствует, запрос прекращает выполнение сразу после считывания необходимого количества различных строк.
- Блоки данных выводятся по мере их обработки, не дожидаясь завершения выполнения всего запроса.