Skip to content

Сортировка результатов. Order by

При выборке данных из БД мы можем сортировать извлекаемые данные в нужном нам порядке. Использование сортировки поможет сделать получаемые данные более удобочитаемыми и воспринимаемыми для анализа человеком.

Подготовка тестовых данных

Создадим таблицу, которая будет содержать список блюд ресторана:

sql
create table dishes(
    name varchar2(100) not null,
    price number(5,2) not null,
    rating number(5)
);

comment on column dishes.name is 'Наименование блюда';
comment on column dishes.price is 'Стоимость за одну порцию';
comment on column dishes.rating is 'Популярность блюда';

insert into dishes(name, price, rating)
values ('Макароны с сыром', 20.56, 320);

insert into dishes(name, price, rating)
values ('Борщ', 10, 130);

insert into dishes(name, price, rating)
values ('Чай с лимоном', 1.34, 270);

insert into dishes(name, price, rating)
values ('Чай с молоком', 1.20, 280);

insert into dishes(name, price, rating)
values ('Свиная отбивная', 30.50, 320);

insert into dishes(name, price, rating)
values ('Овощной салат', 5.70, null);
create table dishes(
    name varchar2(100) not null,
    price number(5,2) not null,
    rating number(5)
);

comment on column dishes.name is 'Наименование блюда';
comment on column dishes.price is 'Стоимость за одну порцию';
comment on column dishes.rating is 'Популярность блюда';

insert into dishes(name, price, rating)
values ('Макароны с сыром', 20.56, 320);

insert into dishes(name, price, rating)
values ('Борщ', 10, 130);

insert into dishes(name, price, rating)
values ('Чай с лимоном', 1.34, 270);

insert into dishes(name, price, rating)
values ('Чай с молоком', 1.20, 280);

insert into dishes(name, price, rating)
values ('Свиная отбивная', 30.50, 320);

insert into dishes(name, price, rating)
values ('Овощной салат', 5.70, null);

Овощной салат - новинка в меню, и его еще не успели оценить посетители; Именно поэтому в колонке rating содержится null. Конечно, здесь возможны варианты - например, можно было хранить значение 0 для обозначения отсутствия оценок блюда посетителями, но для демонстрационных целей мы здесь будем хранить null.

Сортировка по возрастанию. Asc

Для того, чтобы получить данные в определенном порядке, используется конструкция order by. Для того, чтобы сортировка выполнялась по возрастанию, к конструкции order by добавляется атрибут asc.

Получим все блюда в из меню и отсортируем их по стоимости начиная с дешевых и заканчивая самыми дорогими:

sql
select *
from dishes
order by price asc
select *
from dishes
order by price asc
NAMEPRICERATING
Чай с молоком1.2280
Чай с лимоном1.34270
Овощной салат5.7-
Борщ10130
Макароны с сыром20.56320
Свиная отбивная30.5320

Сортировка может выполняться одновременно по нескольким полям. Давайте добавим сортировку по рейтингу блюд начиная от самых непопулярных и заканчивая самыми популярными блюдами. При этом, кроме рейтинга мы будем сортировать блюда по стоимости - от дешевых к дорогим:

sql
select *
from dishes
order by rating asc, price asc
select *
from dishes
order by rating asc, price asc
NAMEPRICERATING
Борщ10130
Чай с лимоном1.34270
Чай с молоком1.2280
Макароны с сыром20.56320
Свиная отбивная30.5320
Овощной салат5.7-

Как видно, блюда, которые имеют одинаковый рейтинг, расположились в порядке возрастания их цен.

Сортировка по убыванию. Desc

Для сортировки по убыванию используется desc.

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

sql
select *
from dishes
order by rating desc
select *
from dishes
order by rating desc
NAMEPRICERATING
Овощной салат5.7-
Макароны с сыром20.56320
Свиная отбивная30.5320
Чай с молоком1.2280
Чай с лимоном1.34270
Борщ10130

Порядок сортировки по-умолчанию

Если в конструкции order by не указывать порядок сортировки, то oracle будет производить сортировку по возрастанию.

Т.е. следующий запрос:

sql
select *
from dishes
order by price asc, rating asc
select *
from dishes
order by price asc, rating asc

Аналогичен следующему:

sql
select *
from dishes
order by price, rating
select *
from dishes
order by price, rating

Сортировка по порядковому номеру

Вместо указания колонки, по которой должна производиться сортировка, можно указать ее порядковый номер в выборке. Следующие 2 запроса идентичны:

sql
select price, rating
from dishes
order by price, rating
select price, rating
from dishes
order by price, rating
sql
select price, rating
from dishes
order by 1, 2
select price, rating
from dishes
order by 1, 2

Однако, такого подхода следует избегать, и вот почему.

Предположим, мы написали следующий запрос:

sql
select name, price
from dishes
order by 2 desc
select name, price
from dishes
order by 2 desc

Этот запрос выводит список блюд начиная от самых дорогих и заканчивая самыми дешевыми:

NAMEPRICE
Свиная отбивная30.5
Макароны с сыром20.56
Борщ10
Овощной салат5.7
Чай с лимоном1.34
Чай с молоком1.2

Проходит несколько месяцев, и мы решаем извлекать кроме наименования блюда и его цены еще и рейтинг. Пишется следующий запрос:

sql
select name, rating, price
from dishes
order by 2 desc
select name, rating, price
from dishes
order by 2 desc
NAMERATINGPRICE
Овощной салат-5.7
Макароны с сыром32020.56
Свиная отбивная32030.5
Чай с молоком2801.2
Чай с лимоном2701.34
Борщ13010

Но эти данные идут не в том порядке, который нам нужен! Они отсортированы по рейтингу, а не по стоимости. Это произошло потому, что колонка с ценой теперь третья по счету, а не вторая, и при добавлении в выборку еще одной колонки нужно было проверить order by - блок и изменить порядковый номер для сортировки.

Nulls last. Nulls first

Сортировка производится по определенным значениям. Но что делать, если значение в колонке отсутствует, т.е. в нем содержится null?

Здравый смысл подсказывает, что сортировка по null-значениям невозможна.

Но мы можем указать, где должны располагаться null -значения при сортировке в начале или конце. Достигается это путем использования конструкций nulls last и nulls first. Использование первой разместит все null - значения в конце, а второй - в начале.

sql
select *
from dishes
order by rating nulls first
select *
from dishes
order by rating nulls first
NAMEPRICERATING
Овощной салат5.7-
Борщ10130
Чай с лимоном1.34270
Чай с молоком1.2280
Свиная отбивная30.5320
Макароны с сыром20.56320
sql
select *
from dishes
order by rating nulls last
select *
from dishes
order by rating nulls last
NAMEPRICERATING
Борщ10130
Чай с лимоном1.34270
Чай с молоком1.2280
Свиная отбивная30.5320
Макароны с сыром20.56320
Овощной салат5.7-