Sql order by по нескольким полям: Как построить sql запрос сортировки по двум полям? — Хабр Q&A
Сортировка в SQL по одному полю, затем по другому
Вы здесь:
Главная — MySQL — SQL — Сортировка в SQL по одному полю, затем по другому
Я уже как-то писал про сортировку сразу по нескольким полям в SQL. Но иногда требуется сортировка не сразу по нескольким полям, а сначала по одному, затем по-другому. Например, в курсе, который я сейчас записываю, мне потребовалось вывести 8 новинок из таблицы и отсортировать эти 8 новинок по цене. Не сразу по новизне и цене, а именно сначала новинки, а потом сортировка. Давайте с Вами разберём, как делается сортировка в SQL сначала по одному полю, затем по другому.
Безусловно, можно просто извлечь 8 новинок, а потом в PHP уже отсортировать по цене, но это весьма сомнительное решение. Вот как это можно сделать сразу в SQL:
SELECT * FROM
(SELECT * FROM `table` ORDER BY `date` DESC LIMIT 8) a
ORDER BY `price`
Как видите, получился такой достаточно хитрый запрос. Мы после первого FROM не писали название таблицы, а указали множество данных, полученных выборкой из другой таблицы. И вот из этой другой таблицы выбирается 8 новинок, а потом в полученном множестве идёт уже сортировка по цене.
Таким образом, PHP нам не потребовался, хотя абсолютное большинство в такой ситуации к этому обязательно бы прибегнули.
-
Создано 14.02.2013 21:25:36 -
Михаил Русаков
Предыдущая статья Следующая статья
Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!
Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.
Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления
Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.
Порекомендуйте эту статью друзьям:
Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):
-
Кнопка:
<a href=»https://myrusakov.ru» target=»_blank»><img src=»https://myrusakov.ru/images/button.gif» alt=»Как создать свой сайт» /></a>Она выглядит вот так:
-
Текстовая ссылка:
<a href=»https://myrusakov.ru» target=»_blank»>Как создать свой сайт</a>Она выглядит вот так: Как создать свой сайт
- BB-код ссылки для форумов (например, можете поставить её в подписи):
[URL=»https://myrusakov.ru»]Как создать свой сайт[/URL]
Двойная сортировка на SQL
Вы здесь:
Главная — MySQL — SQL — Двойная сортировка на SQL
В большинстве случаев, когда из базы данных выводится множество записей, требуется их сортировка по какому-либо полю. Либо по алфавиту, либо по id, либо по какому-либо другому параметру. Но иногда возникает ситуация, когда требуется сделать двойную сортировку в SQL-запросе. Давайте разберём, когда она может потребоваться и, главное, как её провести.
Допустим, у нас имеется примерно такая таблица:
login |
amount |
a | 20 |
a | 15 |
b | 12 |
c | 14 |
b | 19 |
с | 10 |
Нам нужно отсортировать все записи по полю login, а затем внутри этого login отсортировать по amount. То есть чтобы у нас получился такой результат:
login |
amount |
a | 15 |
a | 20 |
b | 12 |
b | 19 |
с | 10 |
c | 14 |
К счастью, в SQL двойная сортировка делается просто элементарно:
SELECT * FROM `my_table` ORDER BY `login`, `amount`
После выполнения этого запроса Вы получите как раз требуемый результат. Вот таким простым способом делается двойная сортировка прямо в SQL-запросе.
-
Создано 12.12.2012 09:33:46 -
Михаил Русаков
Предыдущая статья Следующая статья
Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!
Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.
Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления
Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.
Порекомендуйте эту статью друзьям:
Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):
-
Кнопка:
<a href=»https://myrusakov.ru» target=»_blank»><img src=»https://myrusakov.ru/images/button.gif» alt=»Как создать свой сайт» /></a>Она выглядит вот так:
-
Текстовая ссылка:
<a href=»https://myrusakov.ru» target=»_blank»>Как создать свой сайт</a>Она выглядит вот так: Как создать свой сайт
- BB-код ссылки для форумов (например, можете поставить её в подписи):
[URL=»https://myrusakov.ru»]Как создать свой сайт[/URL]
MySQL | Сортировка. ORDER BY
Сортировка. ORDER BY
Последнее обновление: 16.05.2018
Оператор ORDER BY сортируют значения по одному или нескольких столбцам. Например, упорядочим выборку из таблицы Products
по столбцу Price:
SELECT * FROM Products ORDER BY Price;
Также можно производить упорядочивание данных по псевдониму столбца, который определяется с помощью оператора AS:
SELECT ProductName, ProductCount * Price AS TotalSum FROM Products ORDER BY TotalSum;
В качестве критерия сортировки также можно использовать сложно выражение на основе столбцов:
SELECT ProductName, Price, ProductCount FROM Products ORDER BY ProductCount * Price;
Сортировка по убыванию
По умолчанию данные сортируются по возрастанию, однако с помощью оператора DESC можно задать сортировку по убыванию.
SELECT ProductName, ProductCount FROM Products ORDER BY ProductCount DESC;
По умолчанию вместо DESC используется оператор ASC, который сортирует по возрастанию:
SELECT ProductName, ProductCount FROM Products ORDER BY ProductCount ASC;
Сотировка по нескольким столбцам
При сортировке сразу по нескольким столбцам все эти столбцы указываются через запятую после оператора ORDER BY:
SELECT ProductName, Price, Manufacturer FROM Products ORDER BY Manufacturer, ProductName;
Здесь строки сначала сортируются по столбцу Manufacturer по возрастанию. Затем если есть две строки, в которых столбец Manufacturer
имеет одинаковое значение, то они сортируются по столбцу ProductName также по возрастанию. Но опять же с помощью ASC и DESC можно отдельно для
разных столбцов определить сортировку по возрастанию и убыванию:
SELECT ProductName, Price, Manufacturer FROM Products ORDER BY Manufacturer ASC, ProductName DESC;
Некоторые примеры нестандартных возможностей синтаксиса Oracle SQL / Хабр
Введение
Примерно полтора года назад я сдал экзамены на OCP Advanced PL/SQL Developer, далее специфика работы несколько изменилась, и после стандартного производственного использования Oracle я занимался разработкой архитектуры двухуровневой клиент-серверной системы на основе Oracle для нужд компьютерной лингвистики. Далее был этап развития системы и решения наукоемких задач на ее основе, пришлось заниматься использованием иерархических запросов в решении нестандартных задач и другими специфическими вещами. Результатом углубления в специфику стало некоторое «проседание» базы, а значит, наступило время снова просмотреть материалы, использовавшиеся для подготовки к экзаменам.
Ниже будет приведено несколько нестандартных примеров использования sql-запросов. Такие примеры обычно приходят на ум во время просмотра конспекта, проверяются, обсуждаются с другими специалистами и забываются. В этот раз мне захотелось сохранить некоторые из них в sql-файле, позже стала понятна необходимость в комментариях к каждому запросу. Так и появилась эта заметка.
Несколько слов о специфике оператора order by
Как вы думаете, будет ли ошибка в результате выполнения данного запроса?
--Запрос №1
select * from dual
order by 1+2||dummy
Ответ: ошибки не будет, т.к. спецификация order by определена следующим образом:
ORDER BY {col(s)|expression|numeric_pos} [ASC|DESC] [NULLS FIRST|LAST];
Где expression — A sort key expression, such as numeric, string, and datetime expressions. Expression can also be a row value expression such as a scalar subquery or case expression.
Подробнее, например, здесь download.oracle.com/javadb/10.6.2.1/ref/rrefsqlj13658.html
Таким образом, мы отсортировали таблицу dual по выражению «3X», что бессмысленно, однако в качестве выражения для сортировки можно, например, использовать выражение с функцией substr. Важна сама возможность использования выражений.
Как мы знаем, таблица dual содержит один столбец, вернет ли ошибку такой запрос:
--Запрос №2
select * from dual
order by 2
А такой?
--Запрос №3
select * from dual
order by 2+0
В первом случае мы имеем дело с позиционным указанием колонок – т.е. ссылкой на колонку №2, которой не существует, соответственно, получим ошибку.
Во втором случае мы имеем дело с выражением, т.е. это уже не номер колонки, а сортировка по числу 2, аналогичная сортировке по строке «3X» в запросе №1. Поэтому ошибки не будет.
Посмотрите на следующий пример. Какой порядок строк мы получим в результате выполнения этого запроса? Будет ли ошибка?
--Запрос №4
select 3, dummy from dual
union all
select 2, dummy from dual
order by "3"
Union all не сортирует строки объединяемых множеств (в отличии от union), т.е. без order by мы получим строки в указанном в запросе порядке (union all гарантирует сохранение исходного порядка строк). Теперь настала очередь order by, главный вопрос, что такое «3» в этом случае? Поскольку у нас использованы двойные кавычки «, а не одинарные ‘, то «3» – это алиас колонки. Как известно, операции с множествами требуют использования сходных типов данных, а имена колонок берутся из первого запроса, поскольку мы явно не указали имя первой колонки, то, по умолчанию, она получила имя выражения, т.е. «3». Работа с такими алиасами показана, например, в запросе №5 (главное не забывать про аппер-кейс).
Сортировка по умолчанию – всегда asc, т.е. результаты запроса №4 сортируются по первой колонке по возрастанию. Результат: строка «2, Х», потом «3, Х».
--Запрос №5
select substr(dummy,1,1) from dual
order by "SUBSTR(DUMMY,1,1)"
Повторим эксперимент из запроса №3 на множествах. Каким будет результат запроса?
--Запрос №6
select 3, dummy from dual
union all
select 2, dummy from dual
order by 2+0
Может показаться, что результат запроса будет следующим: строка «3, Х» потом «2, Х». Предпосылки для этого следующие: данный порядок гарантирует union all, а выражение 2+0 не повлияет на сортировку записей (что показано в запросе №7). Так бы оно и было, если бы не одно «но»: в операциях с множествами order by можно использовать только в конце составного запроса с именами или номерами столбцов первого запроса, выражения не допускаются:
For compound queries containing set operators UNION, INTERSECT, MINUS, or UNION ALL, the ORDER BY clause must specify positions or aliases rather than explicit expressions. Also, the ORDER BY clause can appear only in the last component query. The ORDER BY clause orders all rows returned by the entire compound query. download.oracle.com/docs/cd/B19306_01/server.102/b14200/queries005.htm#i2053998
Поэтому запрос №6 вернет ошибку.
--Запрос №7
select * from
(select 3, dummy from dual
union all
select 2, dummy from dual)
order by 2+0
Использование not in
Наверняка, большинство людей, прошедших различные курсы, помнят, что следует избегать оператора not in, а сходную функциональность можно получить, используя операторы in либо exists. Причина такого негативного отношения к not in кроется в специфике его работы с null-значениями.
Определите результат выполнения следующего запроса:
--Запрос №1
select * from dual
where 1 not in (select 2 from dual union select null from dual)
Для начала рассмотрим такой запрос:
--Запрос №2
select * from dual
where 2 in (select 2 from dual union select null from dual)
Ничего необычного в запросе №2 нет: подзапрос возвращает множество из двух строк со значениями «2» и «null», условие where принимает значение true, весь запрос №2 возвращает 1 строку – стандартное поведение.
Теперь рассмотрим разницу в поведении in и not in, здесь нам понадобятся знания о null-арифметике:
1) Любые арифметические операции с null возвращают null
2) Булевые операторы с null работают следующим образом:
- null AND false = false
- false AND null = false
- null AND true = null
- true AND null = null
- null OR true = true
- true OR null = true
- null OR false = null
- false OR null = null
Пока все логично. Теперь рассмотрим, как работает IN в запросе №2:
2 IN (2,null) => (2=2) OR (2=null) => true OR null => true
Рассмотрим работу NOT IN в запросе №1:
1 NOT IN (2, null) => (1!=2) AND (1!=null) => true AND null => null
Таким образом, условие where в запросе №1 преобразуется в null, если хотя бы один операнд null, поэтому весь запрос №1 приблизительно эквивалентен следующему запросу:
--Запрос №3
select * from dual
where null=null
Очевидно, что запрос №3 не вернет ни одной строки, соответственно, запрос №1 также не вернет ни одной строки.
Неявное преобразование типов
Тема явного и неявного преобразования типов очень обширна, поэтому, не пытаясь охватить ее в целом, я хотел бы рассмотреть лишь один пример. Пускай сегодня 10.09.11 10:00:00 и Оракл сконфигурирован так, что формат DD.MM.RR распознается по умолчанию, какой из запросов вернет одну строку?
--Запрос №1
select * from dual where sysdate>'10.09.11';
--Запрос №2
select * from dual where sysdate||''='10.09.11';
Ответ – оба. Почему так и как это, вообще, возможно? Ответ лежит в механизме неявного преобразования типов.
Рассмотрим запрос №1: в where мы сравниваем дату со строкой, в этом случае Оракл пытается преобразовать строку в дату, если формат строки соответствует одному из форматов даты по умолчанию (формат даты по умолчанию для сессии можно посмотреть в параметре NLS_DATE_FORMAT, выполнив запрос
select * from nls_session_parameters). Если формат строки не отвечает формату даты по умолчанию, то получим ошибку. В нашем случае форматы соответствуют и строка ‘10.09.11’ преобразуется в дату 10.09.11 00:00:00, поскольку sysdate = 10.09.11 10:00:00, то запрос №1 вернет 1 строку.
Рассмотрим запрос №2: в where происходит конкатенация даты со строкой, результатом такой операции будет строка, причем при неявном преобразовании даты в строку происходит урезание данных до формата DD.MM.RR, т.е. мы сравниваем две строки ‘10.09.11’ и ‘10.09.11’. В результате условие where выполняется, и запрос возвращает одну строку.
Заключение
Приведенный обзор не претендует на полноту освещения какой-либо функциональности Oracle, создан «for fun» и призван продемонстрировать несколько случаев нестандартного использования возможностей синтаксиса sql.
Поиск дубликатов MySQL
Сборник запросов для поиска, изменения и удаления дублей в таблице MySQL по одному и нескольким полям. В примерах все запросы будут применятся к следующий таблице:
1
Поиск дубликатов
Подсчет дублей
Запрос подсчитает количество всех записей с одинаковыми значениями в поле `col1`
.
SELECT
`col1`,
COUNT(`col1`) AS `count`
FROM
`table`
GROUP BY
`col1`
HAVING
`count` > 1
Результат:
Подсчет дубликатов по нескольким полям:
SELECT
`col1`,
`col2`,
COUNT(*) AS `count`
FROM
`table`
GROUP BY
`col1`,`col2`
HAVING
`count` > 1
Результат:
Все записи с одинаковыми значениями
Запрос найдет все записи с одинаковыми значениями в `col1`
.
SELECT
*
FROM
`table`
WHERE
`col1` IN (SELECT `col1` FROM `table` GROUP BY `col1` HAVING COUNT(*) > 1)
ORDER BY
`col1`
Результат:
Для одинаковых значений в `col1`
и `col2`
:
SELECT
*
FROM
`table`
WHERE
`col1` IN (SELECT `col1` FROM `table` GROUP BY `col1` HAVING COUNT(*) > 1)
AND `col2` IN (SELECT `col2` FROM `table` GROUP BY `col2` HAVING COUNT(*) > 1)
ORDER BY
`col1`
Получить только дубликаты
Запрос получит только дубликаты, в результат не попадают записи с самым ранним `id`
.
SELECT
`table`.*
FROM
`table`
LEFT OUTER JOIN
(SELECT MIN(`id`) AS `id`, `col1` FROM `table` GROUP BY `col1`) AS `tmp`
ON
`table`.`id` = `tmp`.`id`
WHERE
`tmp`.`id` IS NULL
Результат:
Для нескольких полей:
SELECT
`table`.*
FROM
`table`
LEFT OUTER JOIN
(SELECT MIN(`id`) AS `id`, `col1`, `col2` FROM `table` GROUP BY `col1`, `col2`) AS `tmp`
ON
`a`.`id` = `tmp`.`id`
WHERE
`tmp`.`id` IS NULL
2
Уникализация записей
Запрос сделает уникальные названия только у дублей, дописав `id`
в конец `col1`
.
UPDATE
`table`
LEFT OUTER JOIN
(SELECT MIN(`id`) AS `id`, `col1` FROM `table` GROUP BY `col1`) AS `tmp`
ON
`table`.`id` = `tmp`.`id`
SET
`table`.`col1` = CONCAT(`table`.`col1`, '-', `table`.`id`)
WHERE
`tmp`.`id` IS NULL
Результат:
По нескольким полям:
UPDATE
`table`
LEFT OUTER JOIN
(SELECT MIN(`id`) AS `id`, `col1`, `col2` FROM `table` GROUP BY `col1`, `col2`) AS `tmp`
ON
`table`.`id` = `tmp`.`id`
SET
`table`.`col1` = CONCAT(`table`.`col1`, '-', `table`.`id`)
WHERE
`tmp`.`id` IS NULL
3
Удаление дубликатов
Удаление дублирующихся записей, останутся только уникальные.
DELETE
`table`
FROM
`table`
LEFT OUTER JOIN
(SELECT MIN(`id`) AS `id`, `col1` FROM `table` GROUP BY `col1`) AS `tmp`
ON
`table`.`id` = `tmp`.`id`
WHERE
`tmp`.`id` IS NULL
По нескольким полям:
DELETE
`table`
FROM
`table`
LEFT OUTER JOIN
(SELECT MIN(`id`) AS `id`, `col1`, `col2` FROM `table` GROUP BY `col1`, `col2`) AS `tmp`
ON
`table`.`id` = `tmp`.`id`
WHERE
`tmp`.`id` IS NULL
sql — определяет порядок полей многоколоночного индекса в MySQL Matter
Переполнение стека
- Около
Продукты
- Для команд
Переполнение стека
Общественные вопросы и ответыПереполнение стека для команд
Где разработчики и технологи делятся частными знаниями с коллегамиВакансии
Программирование и связанные с ним технические возможности карьерного ростаТалант
Нанимайте технических специалистов и создавайте свой бренд работодателяРеклама
Обратитесь к разработчикам и технологам со всего мира- О компании
Загрузка…
.
Сортировка данных в SQL, порядок операторов по
При выполнении запроса SELECT строки по умолчанию возвращаются в неопределенном порядке. Фактический порядок строк в этом случае зависит от плана подключения и сканирования, а также от порядка данных на диске, поэтому вы не можете полагаться на него. Оператор ORDER BY используется для организации записей.
Общая структура запроса с оператором ORDER BY
MySQL
SELECT table_fields FROM list_of_tables
ЗАКАЗАТЬ ПО table_field_1 [ASC | DESC] [, table_field_n [ASC | DESC]]
В описанной структуре запроса необязательные параметры указаны в квадратных скобках.
- DESC — сортировка по убыванию
- ASC (по умолчанию) — сортировка по возрастанию
Сортировка по нескольким столбцам
Для сортировки результатов по двум или более столбцам они должны быть разделены запятыми.
MySQL
ВЫБРАТЬ Поля_таблиц из списка_таблиц
ORDER BY table_field_1 [ASC | DESC],
поле_таблицы_2 [ASC | DESC];
Данные будут отсортированы по первому столбцу, но если есть несколько записей с совпадающими значениями в первом столбце, то они будут отсортированы по второму столбцу.Количество столбцов, по которым вы можете сортировать, не ограничено.
Правило сортировки применяется только к следующему за ним столбцу.
ORDER BY column_1, column_2 DESC
не то же самое, что
ORDER BY column_1 DESC, column_2 DESC
Примеры
Перечислить названия авиакомпаний в алфавитном порядке из таблицы Company:
MySQL
SELECT name FROM Company
ЗАКАЗАТЬ ПО имени;
Сортировка строковых данных осуществляется в лексикографическом (алфавитном) порядке.
Отобразить всю информацию о рейсе, отсортированную по времени вылета самолета в порядке возрастания и по времени прибытия в аэропорт в порядке убывания, из таблицы поездки:
MySQL
SELECT * FROM Trip
ORDER BY time_out, time_in DESC;
В этом примере информация сортируется в начале по времени отправления. Затем, если время отправления совпадает, оно сортируется по времени прибытия.
Вывести все данные о покупках, сделанных Хедли Куинси, отсортировав их по убыванию стоимости товаров:
1.Сначала вам нужно узнать идентификатор Хедли Куинси в таблице FamilyMembers:
MySQL
SELECT member_id от FamilyMembers
ГДЕ member_name = 'Хедли Куинси';
2. Получите все данные о покупках, сделанных Хедли Куинси, из таблицы Payments:
MySQL
SELECT * FROM Payments
ГДЕ family_member = (
ВЫБЕРИТЕ member_id из FamilyMembers
ГДЕ member_name = 'Хедли Куинси'
);
3. Отсортируйте полученные данные в порядке убывания стоимости товара:
MySQL
SELECT * FROM Payments
ГДЕ family_member = (
ВЫБЕРИТЕ member_id из FamilyMembers
ГДЕ member_name = 'Хедли Куинси'
) ORDER BY unit_price DESC;
.