Order by select: Предложение ORDER BY (Transact-SQL) — SQL Server
Содержание
ORDER BY | Документация ClickHouse
- Справка по SQL
- Выражения
- SELECT
Секция ORDER BY
содержит список выражений, к каждому из которых также может быть приписано DESC
или ASC
(направление сортировки). Если ничего не приписано — это аналогично приписыванию ASC
. ASC
— сортировка по возрастанию, DESC
— сортировка по убыванию. Обозначение направления сортировки действует на одно выражение, а не на весь список. Пример: ORDER BY Visits DESC, SearchPhrase
.
Если вы хотите для сортировки данных указывать номера столбцов, а не названия, включите настройку enable_positional_arguments.
Строки, для которых список выражений, по которым производится сортировка, принимает одинаковые значения, выводятся в произвольном порядке, который может быть также недетерминированным (каждый раз разным).
Если секция ORDER BY отсутствует, то, аналогично, порядок, в котором идут строки, не определён, и может быть недетерминированным.
Сортировка специальных значений
Существует два подхода к участию NaN
и NULL
в порядке сортировки:
- По умолчанию или с модификатором
NULLS LAST
: сначала остальные значения, затемNaN
, затемNULL
. - С модификатором
NULLS FIRST
: сначалаNULL
, затемNaN
, затем другие значения.
Пример
Для таблицы
┌─x─┬────y─┐
│ 1 │ ᴺᵁᴸᴸ │
│ 2 │ 2 │
│ 1 │ nan │
│ 2 │ 2 │
│ 3 │ 4 │
│ 5 │ 6 │
│ 6 │ nan │
│ 7 │ ᴺᵁᴸᴸ │
│ 6 │ 7 │
│ 8 │ 9 │
└───┴──────┘
Выполните запрос SELECT * FROM t_null_nan ORDER BY y NULLS FIRST
чтобы получить:
┌─x─┬────y─┐
│ 1 │ ᴺᵁᴸᴸ │
│ 7 │ ᴺᵁᴸᴸ │
│ 1 │ nan │
│ 6 │ nan │
│ 2 │ 2 │
│ 2 │ 2 │
│ 3 │ 4 │
│ 5 │ 6 │
│ 6 │ 7 │
│ 8 │ 9 │
└───┴──────┘
При сортировке чисел с плавающей запятой NaNs отделяются от других значений. Независимо от порядка сортировки, NaNs приходят в конце. Другими словами, при восходящей сортировке они помещаются так, как будто они больше всех остальных чисел, а при нисходящей сортировке они помещаются так, как будто они меньше остальных.
Поддержка collation
Для сортировки по значениям типа String есть возможность указать collation (сравнение). Пример: ORDER BY SearchPhrase COLLATE 'tr'
— для сортировки по поисковой фразе, по возрастанию, с учётом турецкого алфавита, регистронезависимо, при допущении, что строки в кодировке UTF-8. COLLATE
может быть указан или не указан для каждого выражения в ORDER BY независимо. Если есть ASC
или DESC
, то COLLATE
указывается после них. При использовании COLLATE
сортировка всегда регистронезависима.
Сравнение поддерживается при использовании типов LowCardinality, Nullable, Array и Tuple.
Рекомендуется использовать COLLATE
только для окончательной сортировки небольшого количества строк, так как производительность сортировки с указанием COLLATE
меньше, чем обычной сортировки по байтам.
Примеры с использованием сравнения
Пример с значениями типа String:
Входная таблица:
┌─x─┬─s────┐
│ 1 │ bca │
│ 2 │ ABC │
│ 3 │ 123a │
│ 4 │ abc │
│ 5 │ BCA │
└───┴──────┘
Запрос:
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
Результат:
┌─x─┬─s────┐
│ 3 │ 123a │
│ 4 │ abc │
│ 2 │ ABC │
│ 1 │ bca │
│ 5 │ BCA │
└───┴──────┘
Пример со строками типа Nullable:
Входная таблица:
┌─x─┬─s────┐
│ 1 │ bca │
│ 2 │ ᴺᵁᴸᴸ │
│ 3 │ ABC │
│ 4 │ 123a │
│ 5 │ abc │
│ 6 │ ᴺᵁᴸᴸ │
│ 7 │ BCA │
└───┴──────┘
Запрос:
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
Результат:
┌─x─┬─s────┐
│ 4 │ 123a │
│ 5 │ abc │
│ 3 │ ABC │
│ 1 │ bca │
│ 7 │ BCA │
│ 6 │ ᴺᵁᴸᴸ │
│ 2 │ ᴺᵁᴸᴸ │
└───┴──────┘
Пример со строками в Array:
Входная таблица:
┌─x─┬─s─────────────┐
│ 1 │ ['Z'] │
│ 2 │ ['z'] │
│ 3 │ ['a'] │
│ 4 │ ['A'] │
│ 5 │ ['z','a'] │
│ 6 │ ['z','a','a'] │
│ 7 │ [''] │
└───┴───────────────┘
Запрос:
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
Результат:
┌─x─┬─s─────────────┐
│ 7 │ [''] │
│ 3 │ ['a'] │
│ 4 │ ['A'] │
│ 2 │ ['z'] │
│ 5 │ ['z','a'] │
│ 6 │ ['z','a','a'] │
│ 1 │ ['Z'] │
└───┴───────────────┘
Пример со строками типа LowCardinality:
Входная таблица:
┌─x─┬─s───┐
│ 1 │ Z │
│ 2 │ z │
│ 3 │ a │
│ 4 │ A │
│ 5 │ za │
│ 6 │ zaa │
│ 7 │ │
└───┴─────┘
Запрос:
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
Результат:
┌─x─┬─s───┐
│ 7 │ │
│ 3 │ a │
│ 4 │ A │
│ 2 │ z │
│ 1 │ Z │
│ 5 │ za │
│ 6 │ zaa │
└───┴─────┘
Пример со строками в Tuple:
┌─x─┬─s───────┐
│ 1 │ (1,'Z') │
│ 2 │ (1,'z') │
│ 3 │ (1,'a') │
│ 4 │ (2,'z') │
│ 5 │ (1,'A') │
│ 6 │ (2,'Z') │
│ 7 │ (2,'A') │
└───┴─────────┘
Запрос:
SELECT * FROM collate_test ORDER BY s ASC COLLATE 'en';
Результат:
┌─x─┬─s───────┐
│ 3 │ (1,'a') │
│ 5 │ (1,'A') │
│ 2 │ (1,'z') │
│ 1 │ (1,'Z') │
│ 7 │ (2,'A') │
│ 4 │ (2,'z') │
│ 6 │ (2,'Z') │
└───┴─────────┘
Деталь реализации
Если кроме ORDER BY
указан также не слишком большой LIMIT, то расходуется меньше оперативки. Иначе расходуется количество памяти, пропорциональное количеству данных для сортировки. При распределённой обработке запроса, если отсутствует GROUP BY, сортировка частично делается на удалённых серверах, а на сервере-инициаторе запроса производится слияние результатов. Таким образом, при распределённой сортировке, может сортироваться объём данных, превышающий размер памяти на одном сервере.
Существует возможность выполнять сортировку во внешней памяти (с созданием временных файлов на диске), если оперативной памяти не хватает. Для этого предназначена настройка max_bytes_before_external_sort
. Если она выставлена в 0 (по умолчанию), то внешняя сортировка выключена. Если она включена, то при достижении объёмом данных для сортировки указанного количества байт, накопленные данные будут отсортированы и сброшены во временный файл. После того, как все данные будут прочитаны, будет произведено слияние всех сортированных файлов и выдача результата. Файлы записываются в директорию /var/lib/clickhouse/tmp/
(по умолчанию, может быть изменено с помощью параметра tmp_path
) в конфиге.
На выполнение запроса может расходоваться больше памяти, чем max_bytes_before_external_sort
. Поэтому, значение этой настройки должно быть существенно меньше, чем max_memory_usage
. Для примера, если на вашем сервере 128 GB оперативки, и вам нужно выполнить один запрос, то выставите max_memory_usage
в 100 GB, а max_bytes_before_external_sort
в 80 GB.
Внешняя сортировка работает существенно менее эффективно, чем сортировка в оперативке.
Оптимизация чтения данных
Если в списке выражений в секции ORDER BY
первыми указаны те поля, по которым проиндексирована таблица, по которой строится выборка, такой запрос можно оптимизировать — для этого используйте настройку optimize_read_in_order.
Когда настройка optimize_read_in_order
включена, при выполнении запроса сервер использует табличные индексы и считывает данные в том порядке, который задан списком выражений ORDER BY
. Поэтому если в запросе установлен LIMIT, сервер не станет считывать лишние данные. Таким образом, запросы к большим таблицам, но имеющие ограничения по числу записей, выполняются быстрее.
Оптимизация работает при любом порядке сортировки ASC
или DESC
, но не работает при использовании группировки GROUP BY и модификатора FINAL.
Когда настройка optimize_read_in_order
отключена, при выполнении запросов SELECT
табличные индексы не используются.
Для запросов с сортировкой ORDER BY
, большим значением LIMIT
и условиями отбора WHERE, требующими чтения больших объемов данных, рекомендуется отключать optimize_read_in_order
вручную.
Оптимизация чтения данных поддерживается в следующих движках:
В движке MaterializedView
оптимизация поддерживается при работе с сохраненными запросами (представлениями) вида SELECT ... FROM merge_tree_table ORDER BY pk
. Но оптимизация не поддерживается для запросов вида SELECT ... FROM view ORDER BY pk
, если в сохраненном запросе нет секции ORDER BY
.
Модификатор ORDER BY expr WITH FILL
Этот модификатор также может быть скобинирован с модификатором LIMIT … WITH TIES
Модификатор WITH FILL
может быть установлен после ORDER BY expr
с опциональными параметрами FROM expr
, TO expr
и STEP expr
.
Все пропущенные значения для колонки expr
будут заполнены значениями, соответствующими предполагаемой последовательности значений колонки, другие колонки будут заполнены значениями по умолчанию.
Используйте следующую конструкцию для заполнения нескольких колонок с модификатором WITH FILL
с необязательными параметрами после каждого имени поля в секции ORDER BY
.
ORDER BY expr [WITH FILL] [FROM const_expr] [TO const_expr] [STEP const_numeric_expr], ... exprN [WITH FILL] [FROM expr] [TO expr] [STEP numeric_expr]
WITH FILL
может быть применен к полям с числовыми (все разновидности float, int, decimal) или временными (все разновидности Date, DateTime) типами. В случае применения к полям типа String
недостающие значения заполняются пустой строкой.
Когда не определен FROM const_expr
, последовательность заполнения использует минимальное значение поля expr
из ORDER BY
.
Когда не определен TO const_expr
, последовательность заполнения использует максимальное значение поля expr
из ORDER BY
.
Когда STEP const_numeric_expr
определен, const_numeric_expr
интерпретируется «как есть» для числовых типов, как «дни» для типа Date
и как «секунды» для типа DateTime
.
Когда STEP const_numeric_expr
не указан, тогда используется 1.0
для числовых типов, 1 день
для типа Date и 1 секунда
для типа DateTime.
Пример запроса без использования WITH FILL
:
SELECT n, source FROM (
SELECT toFloat32(number % 10) AS n, 'original' AS source
FROM numbers(10) WHERE number % 3 = 1
) ORDER BY n;
Результат:
┌─n─┬─source───┐
│ 1 │ original │
│ 4 │ original │
│ 7 │ original │
└───┴──────────┘
Тот же запрос после применения модификатора WITH FILL
:
SELECT n, source FROM (
SELECT toFloat32(number % 10) AS n, 'original' AS source
FROM numbers(10) WHERE number % 3 = 1
) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5
Результат:
┌───n─┬─source───┐
│ 0 │ │
│ 0.5 │ │
│ 1 │ original │
│ 1.5 │ │
│ 2 │ │
│ 2.5 │ │
│ 3 │ │
│ 3.5 │ │
│ 4 │ original │
│ 4.5 │ │
│ 5 │ │
│ 5.5 │ │
│ 7 │ original │
└─────┴──────────┘
Для случая с несколькими полями ORDER BY field2 WITH FILL, field1 WITH FILL
порядок заполнения будет соответствовать порядку полей в секции ORDER BY
.
Пример:
SELECT
toDate((number * 10) * 86400) AS d1,
toDate(number * 86400) AS d2,
'original' AS source
FROM numbers(10)
WHERE (number % 3) = 1
ORDER BY
d2 WITH FILL,
d1 WITH FILL STEP 5;
Результат:
┌───d1───────┬───d2───────┬─source───┐
│ 1970-01-11 │ 1970-01-02 │ original │
│ 1970-01-01 │ 1970-01-03 │ │
│ 1970-01-01 │ 1970-01-04 │ │
│ 1970-02-10 │ 1970-01-05 │ original │
│ 1970-01-01 │ 1970-01-06 │ │
│ 1970-01-01 │ 1970-01-07 │ │
│ 1970-03-12 │ 1970-01-08 │ original │
└────────────┴────────────┴──────────┘
Поле d1
не заполняется и использует значение по умолчанию. Поскольку у нас нет повторяющихся значений для d2
, мы не можем правильно рассчитать последователность заполнения для d1
.
Cледующий запрос (с измененым порядком в ORDER BY):
SELECT
toDate((number * 10) * 86400) AS d1,
toDate(number * 86400) AS d2,
'original' AS source
FROM numbers(10)
WHERE (number % 3) = 1
ORDER BY
d1 WITH FILL STEP 5,
d2 WITH FILL;
Результат:
┌───d1───────┬───d2───────┬─source───┐
│ 1970-01-11 │ 1970-01-02 │ original │
│ 1970-01-16 │ 1970-01-01 │ │
│ 1970-01-21 │ 1970-01-01 │ │
│ 1970-01-26 │ 1970-01-01 │ │
│ 1970-01-31 │ 1970-01-01 │ │
│ 1970-02-05 │ 1970-01-01 │ │
│ 1970-02-10 │ 1970-01-05 │ original │
│ 1970-02-15 │ 1970-01-01 │ │
│ 1970-02-20 │ 1970-01-01 │ │
│ 1970-02-25 │ 1970-01-01 │ │
│ 1970-03-02 │ 1970-01-01 │ │
│ 1970-03-07 │ 1970-01-01 │ │
│ 1970-03-12 │ 1970-01-08 │ original │
└────────────┴────────────┴──────────┘
mysql, используйте два select и order by, новое значение
SELECT a.id, a.name, a.ad, c.name, c.phone, c.email,
(
SELECT b.id_user
FROM price_b b
WHERE b.id = a.id
ORDER BY b.date DESC
LIMIT 1
) AS f_user_id
FROM a_emtp a
LEFT JOIN customer c ON
c.id = f_user_id
WHERE a.show = "1"
Привет, зачем показывать эту ошибку: неизвестный столбец ‘f_user_id’ в ‘on clause’
Спасибо
mysql
Поделиться
Источник
lolalola
03 ноября 2010 в 09:49
2 ответа
2
SELECT a.id, a.name, a.ad, c.name, c.phone, c.email,
(
SELECT b.id_user
as f_user_id
FROM price_b b
WHERE b.id = a.id
ORDER BY b.date DESC
LIMIT 1
)
FROM a_emtp a
LEFT JOIN customer c ON
c.id = f_user_id
WHERE a.show = "1"
Вы можете ссылаться на помеченные поля из подзапросов внутри внешних запросов. Вы даже можете отказаться от повторной маркировки и просто использовать «b.id_user».
Поделиться
0xCAFEBABE
03 ноября 2010 в 09:51
0
Вероятно, запятая после c.email отсутствовала.
SELECT a.id, a.name, a.ad, c.name, c.phone, c.email,
(
SELECT b.id_user
FROM price_b b
WHERE b.id = a.id
ORDER BY b.date DESC
LIMIT 1
) AS f_user_id
FROM a_emtp a
LEFT JOIN customer c ON
c.id = f_user_id
WHERE a.show = "1"
Поделиться
Michał Pękała
03 ноября 2010 в 09:53
Похожие вопросы:
Функция ранга в MySQL с предложением Order By
Как это могло (Oracle) SQL: select a.*, rank() over (partition by a.field1 order by a.field2 desc) field_rank from table_a a order by a.field1, a.field2 быть переведенным на MySQL? Этот вопрос…
применить «ORDER BY» к «UNION» (Mysql)
хороший день. Итак, все это есть в названии 🙂 Я ищу, чтобы объединить результат двух запросов и упорядочить результат вместе (как и не один за другим). => Я подумывал о том, чтобы применить Союз и…
MySQL не использует первичный ключ внутри запроса SELECT … ORDER BY. Почему?
У меня есть этот стол MySQL: CREATE TABLE `maillog` ( `Id` varchar(200) NOT NULL DEFAULT ‘Test’, `email` varchar(255) DEFAULT NULL, PRIMARY KEY (`Id`), KEY `email` (`email`) ) ENGINE=MyISAM DEFAULT…
MYSQL оптимизация запросов: постройте отдельные таблицы с помощью ORDER BY done, чтобы не нуждаться в индексах для SELECT ORDER BY
Мне интересно, правильна ли моя теория здесь, поэтому я ищу несколько советов от MySQL гуру. У меня есть таблица, которую я переработал, чтобы просто включить различные элементы, по которым запросы…
Использование ORDER BY, GROUP BY и multiple SELECT вместе
У меня есть два стола TABLE пользователь uid | username —————- 1 | brandon 2 | john 3 | nicole TABLE private_msgs id | from | to | message | time…
MySQL Order By с лимитом до MS SQL Order By
В настоящее время я переписываю хранимую процедуру MySQL в хранимую процедуру MS SQL, и я столкнулся с проблемой. В хранимой процедуре MySQL есть курсор, который выбирает значение на основе его…
Всегда внизу, если (используйте `ORDER BY` в MySQL)
id —- 0 2 1 3 7 1 6 3 1 Я хочу отсортировать значение id в порядке убывания, используя ORDER BY в MySQL. Но если значение id равно 3 , всегда ставьте его на дно. Результат будет таким: id —- 7 6…
Как разрешить «ORDER BY clause is not in SELECT list» MySQL 5.7 с помощью SELECT DISTINCT и ORDER BY
Я установил новый Ubuntu, и мой код получил проблему с MySQL. ( ! ) Warning: PDOStatement::execute(): SQLSTATE[HY000]: General error: 3065 Expression #2 of ORDER BY clause is not in SELECT list,…
Используйте предложение ORDER BY in OVER
Я новичок в T-SQL и оконных функциях. Я не понимаю, почему ниже два запроса дают один и тот же результат: SELECT empid, ordermonth, val, SUM(val) OVER (PARTITION BY empid ORDER BY ordermonth ROWS…
ORDER BY, SELECT заявление, дубликат кода
У меня есть приведенная ниже хранимая процедура, и в зависимости от параметра @AreaNumber она будет выполнять точно такой же запрос, но с другим предложением order by. Есть ли способ объединить эти…
PostgreSQL : Документация: 9.6: 7.5. Сортировка строк : Компания Postgres Professional
7.5. Сортировка строк
После того как запрос выдал таблицу результатов (после обработки списка выборки), её можно отсортировать. Если сортировка не задана, строки возвращаются в неопределённом порядке. Фактический порядок строк в этом случае будет зависеть от плана соединения и сканирования, а также от порядка данных на диске, поэтому полагаться на него нельзя. Определённый порядок выводимых строк гарантируется, только если этап сортировки задан явно.
Порядок сортировки определяет предложение ORDER BY
:
SELECTсписок_выборки
FROMтабличное_выражение
ORDER BYвыражение_сортировки1
[ASC | DESC] [NULLS { FIRST | LAST }] [,выражение_сортировки2
[ASC | DESC] [NULLS { FIRST | LAST }] ...]
Выражениями сортировки могут быть любые выражения, допустимые в списке выборки запроса. Например:
SELECT a, b FROM table1 ORDER BY a + b, c;
Когда указывается несколько выражений, последующие значения позволяют отсортировать строки, в которых совпали все предыдущие значения. Каждое выражение можно дополнить ключевыми словами ASC
или DESC
, которые выбирают сортировку соответственно по возрастанию или убыванию. По умолчанию принят порядок по возрастанию (ASC
). При сортировке по возрастанию сначала идут меньшие значения, где понятие «меньше» определяется оператором <
. Подобным образом, сортировка по возрастанию определяется оператором >
.
Для определения места значений NULL можно использовать указания NULLS FIRST
и NULLS LAST
, которые помещают значения NULL соответственно до или после значений не NULL. По умолчанию значения NULL считаются больше любых других, то есть подразумевается NULLS FIRST
для порядка DESC
и NULLS LAST
в противном случае.
Заметьте, что порядки сортировки определяются независимо для каждого столбца. Например, ORDER BY x, y DESC
означает ORDER BY x ASC, y DESC
, и это не то же самое, что ORDER BY x DESC, y DESC
.
Здесь выражение_сортировки
может быть меткой столбца или номером выводимого столбца, как в данном примере:
SELECT a + b AS sum, c FROM table1 ORDER BY sum; SELECT a, max(b) FROM table1 GROUP BY a ORDER BY 1;
Оба эти запроса сортируют результат по первому столбцу. Заметьте, что имя выводимого столбца должно оставаться само по себе, его нельзя использовать в выражении. Например, это ошибка:
SELECT a + b AS sum, c FROM table1 ORDER BY sum + c; -- неправильно
Это ограничение позволяет уменьшить неоднозначность. Тем не менее неоднозначность возможна, когда в ORDER BY
указано простое имя, но оно соответствует и имени выходного столбца, и столбцу из табличного выражения. В этом случае используется выходной столбец. Эта ситуация может возникнуть, только когда с помощью AS
выходному столбцу назначается то же имя, что имеет столбец в другой таблице.
ORDER BY
можно применить к результату комбинации UNION
, INTERSECT
и EXCEPT
, но в этом случае возможна сортировка только по номерам или именам столбцов, но не по выражениям.
Как использовать DISTINCT и ORDER BY в одном операторе SELECT?
Ключевые столбцы расширенной сортировки
Причина, по которой то, что вы хотите сделать, не работает, заключается в логическом порядке операций в SQL , который для вашего первого запроса (упрощенно):
FROM MonitoringJob
SELECT Category, CreationDate
т.е. добавить так называемый расширенный ключевой столбец сортировкиORDER BY CreationDate DESC
SELECT Category
т.е. снова удалите столбец расширенного ключа сортировки из результата.
Таким образом, благодаря стандартной функции расширенного ключевого столбца сортировки SQL , можно полностью упорядочить то, чего нет в SELECT
предложении, потому что оно временно добавляется к нему за кулисами.
Итак, почему это не работает
DISTINCT
?
Если мы добавим DISTINCT
операцию, она будет добавлена между SELECT
и ORDER BY
:
FROM MonitoringJob
SELECT Category, CreationDate
DISTINCT
ORDER BY CreationDate DESC
SELECT Category
Но теперь, с расширенным ключевым столбцом сортировки CreationDate
, семантикаDISTINCT
операции была изменена, поэтому результат больше не будет прежним. Это не то, что мы хотим, поэтому и стандарт SQL, и все разумные базы данных запрещают такое использование.
обходные
Его можно эмулировать с помощью стандартного синтаксиса следующим образом
SELECT Category
FROM (
SELECT Category, MAX(CreationDate) AS CreationDate
FROM MonitoringJob
GROUP BY Category
) t
ORDER BY CreationDate DESC
Или просто (в данном случае), как показал также Прутсвондер
SELECT Category, MAX(CreationDate) AS CreationDate
FROM MonitoringJob
GROUP BY Category
ORDER BY CreationDate DESC
Я подробно писал о SQL DISTINCT и ORDER BY здесь .
Оператор SQL: ORDER BY. — it-black.ru
Оператор ORDER BY выполняет сортировку выходных значений. Оператор можно применять как к числовым столбцам, так и к строковым. В последнем случае, сортировка будет происходить по алфавиту. Синтаксис оператора:
ORDER BY column_name [ASC | DESC]
Сортировка может производиться как по возрастанию, так и по убыванию значений:
- Параметр ASC (по умолчанию) устанавливает порядок сортирования во возрастанию, от меньших значений к большим.
- Параметр DECS устанавливает порядок сортирования по убыванию, от больших значений к меньшим.
Рассмотрим примеры оператора SQL ORDER BY. Имеется следующая таблица Artists.
Singer | Album | Year | Sale |
The Prodigy | Invaders Must Die | 2008 | 1200000 |
Drowning Pool | Sinner | 2001 | 400000 |
Massive Attack | Mezzanine | 1998 | 2300000 |
The Prodigy | Fat of the Land | 1997 | 600000 |
The Prodigy | Music For The Jilted Generation | 1994 | 1500000 |
Massive Attack | 100th Window | 2003 | 1200000 |
Drowning Pool | Full Circle | 2007 | 800000 |
Massive Attack | Danny The Dog | 2004 | 1900000 |
Drowning Pool | Resilience | 2013 | 500000 |
Пример 1. Выведем все записи таблицы, упорядоченные по названию исполнителя с помощью оператора SQL ORDER BY:
SELECT * FROM Artists ORDER BY Singer;
Пример 2. Выведем названия исполнителя, альбома, год выпуска тех альбомов, которые выпущены после 2001 года, упорядоченные по убыванию года:
SELECT Singer, Album, Year FROM Artists WHERE Year > 2001 ORDER BY Year DESC;
Самостоятельно создайте таблицу Artists и выполните каждый пример. В комментариях можете писать новые примеры к данной таблице и не только.
Видео:
Урок 4. Сортировка в SQL (ORDER BY)
В SQL часто кроме фильтрации данных, также часто требуется отсортировать их по одному из столцов.
В первом уроке мы написали SQL-запрос для получения данных о совершенолетних пользователях. Посмотрим на него еще раз:
SELECT last_name, first_name, birthday FROM users WHERE age >= 18
id | last_name | first_name | birthday |
---|---|---|---|
1 | Иванов | Дмитрий | 1996-12-11 |
3 | Шевченко | Тимур | 1998-04-27 |
4 | Иванова | Светлана | 1993-08-06 |
6 | Иванов | Алексей | 1993-08-05 |
7 | Процук | Алена | 1997-02-28 |
Обратите внимание, что сейчас данные никак не упорядочены. Ни по фамилии, ни по имени, ни по дате рождения. Но давайте добавим после конструции WHERE: ORDER BY last_name:.
SELECT last_name, first_name, birthday
FROM users WHERE age >= 18 ORDER BY last_name
После выполнение данного SQL запроса мы получим таблицу отсортированную по столбцу last_name (фамилия). Так как last_name хранит строки, то сортировка происходит в алфавитном порядке:
id | last_name | first_name | birthday |
---|---|---|---|
1 | Иванов | Дмитрий | 1996-12-11 |
6 | Иванов | Алексей | 1993-08-05 |
4 | Иванова | Светлана | 1993-08-06 |
7 | Процук | Алена | 1997-02-28 |
3 | Шевченко | Тимур | 1998-04-27 |
Обратите внимание, что данные отсортированы только по фамилии, но не по другим полям. Однако давайте добавим через запятую еще один столбец, например, first_name:
SELECT last_name, first_name, birthday
FROM users WHERE age >= 18 ORDER BY last_name, first_name
Теперь таблица отсортирована сразу по двум поля, сперва по фамилии, а уже затем по имени:
id | last_name | first_name | birthday |
---|---|---|---|
6 | Иванов | Алексей | 1993-08-05 |
1 | Иванов | Дмитрий | 1996-12-11 |
4 | Иванова | Светлана | 1993-08-06 |
7 | Процук | Алена | 1997-02-28 |
3 | Шевченко | Тимур | 1998-04-27 |
Разумеется, сортировать можно не только по текстовым полям. Например, можно написать ORDER BY birthday:
SELECT last_name, first_name, birthday
FROM users
WHERE age >= 18
ORDER BY birthday
И получить данные упорядоченные по дате рождения в хронологическом порядке:
id | last_name | first_name | birthday |
---|---|---|---|
6 | Иванов | Алексей | 1993-08-05 |
4 | Иванова | Светлана | 1993-08-06 |
1 | Иванов | Дмитрий | 1996-12-11 |
7 | Процук | Алена | 1997-02-28 |
3 | Шевченко | Тимур | 1998-04-27 |
А если в конструкции ORDER BY после имени столца написать DESC, то данные будут отсортированы в обратном порядке — свежие даты выше:
id | last_name | first_name | birthday |
---|---|---|---|
3 | Шевченко | Тимур | 1998-04-27 |
7 | Процук | Алена | 1997-02-28 |
1 | Иванов | Дмитрий | 1996-12-11 |
4 | Иванова | Светлана | 1993-08-06 |
6 | Иванов | Алексей | 1993-08-05 |
Более того при сортировке данных по нескольким столцам, мы можем для разных столцов указывать разные направления сортировки. Например ORDER BY last_name, birthday DESC:
SELECT last_name, first_name, birthday
FROM users
WHERE age >= 18
ORDER BY last_name, birthday DESC
Тогда данные будут сперва отсортированы в алфавитном порядке по фамилии, а уже внутри каждой фамилии по дате рождения в обратном порядке:
id | last_name | first_name | birthday |
---|---|---|---|
6 | Иванов | Алексей | 1993-08-05 |
1 | Иванов | Дмитрий | 1996-12-11 |
4 | Иванова | Светлана | 1993-08-06 |
7 | Процук | Алена | 1997-02-28 |
3 | Шевченко | Тимур | 1998-04-27 |
Оптимизация ORDER BY RAND() — Highload.today
Как выбрать случайную запись из таблицы в Mysql?SELECT id FROM files **ORDER BY rand()** LIMIT 1;
Но такие запросы работают очень медленно. Посмотрим на EXPLAIN:**EXPLAIN** SELECT id FROM files ORDER BY rand() LIMIT 1;
Увидим, что Mysql создает временную таблицу и использует сортировку всех данных. Такой запрос будет работать все медленнее при наполнении таблицы:
+----+-----+------+----------------------------------------------+ | id | ... | rows | Extra | +----+-----+------+----------------------------------------------+ | 1 | ... | ***4921 | Using index; Using temporary; Using filesort*** | +----+-----+------+----------------------------------------------+
Правильным решением будет использование индекса и избавление от ORDER BY RAND(). Для этого нужно:
- Определить максимальное значение ID (да, такая колонка должна быть и она должна быть ключом) в таблице.
- Получить любое случайное число от нуля до максимального ID.
- Выбрать первую запись из таблицы, где ID больше указанного случайного числа, отсортировав ее по этой же колонке.
Если перевести все в запрос:SELECT f.id FROM files f
JOIN ( SELECT RAND() * (SELECT MAX(id) FROM files) AS max_id ) AS m
WHERE f.id >= m.max_id
ORDER BY f.id ASC
LIMIT 1;
## Эффективная замена ORDER BY RAND()
Как это работает
- Во вложенном запросе мы определяем максимальное значение ID. Допустим оно будет 100000.
- Дальше умножаем это значение на функцию RAND(). Она возвращает значение от 0 до 1. Пусть в примере будет 0.5. Тогда результат умножения будет 50000.
- После этого это значение с помощью JOIN прибавляется в каждой строке оригинальной таблицы.
- Фильтр f.id >= m.max_id выберет первую попавшуюся запись, ID которой будет больше 50000.
- Поскольку мы использовали сортировку ORDER BY f.id ASC, все пропущенные записи будут иметь значение меньше 50000.
- Это значит, что мы выбрали случайную запись из всей таблицы. Но в отличие от ORDER BY RAND(), мы использовали сортировку и фильтрацию по индексу ID (а значит эффективно).
Скорость такого запроса будет в несколько раз быстрее, чем оригинального:
mysql> SELECT id FROM files ORDER BY rand() LIMIT 1; +-------+ | id | +-------+ | 72643 | +-------+ ***1 row in set (0.17 sec)***
Ускоренная версия:
mysql> SELECT f.id FROM files f JOIN ( SELECT rand() * (SELECT max(id) from files) AS max_id ) AS m WHERE f.id >= m.max_id ORDER BY f.id ASC LIMIT 1; +-------+ | id | +-------+ | 86949 | +-------+ **1 row in set (0.00 sec)**
Теперь работает быстро и не зависит от размера таблицы.
Highload нужны авторы технических текстов. Вы наш человек, если разбираетесь в разработке, знаете языки программирования и умеете просто писать о сложном!
Откликнуться на вакансию можно здесь.
sql — как работает SELECT TOP, если порядок не указан?
В документации msdn сказано, что когда мы пишем
ВЫБРАТЬ ВЕРХНЮЮ (N) ..... ЗАКАЗАТЬ [КОЛОННА]
Мы получаем верхние (n) строк, которые отсортированы по столбцу
( по возрастанию
или по убыванию
в зависимости от того, что мы выберем)
Но если мы не укажем порядок по, msdn скажет random
, как указала здесь Гейл Эриксон
. Как он указывает, это должно быть неуказанное
, а не случайное
.Но как
указывает на то, что
Томас Ли
Когда TOP используется вместе с предложением ORDER BY, результат
set ограничен первым числом N упорядоченных строк; в противном случае это
возвращает первые N строк ramdom
Итак, я выполнил этот запрос к таблице, у которой нет индексов, сначала я выполнил это ..
ВЫБРАТЬ *
ИЗ
sys.objects так
КУДА
so.object_id НЕ ВХОДИТ (ВЫБЕРИТЕ si.object_id
ИЗ
sys.index_columns si)
И так .type_desc = N'USER_TABLE '
И затем в одной из этих таблиц (на самом деле я пробовал приведенный ниже запрос во всех этих таблицах, возвращенных указанным выше запросом) и я всегда получал одни и те же строки.
ВЫБРАТЬ ВЕРХ (2) *
ИЗ
MstConfigSettings
Это всегда возвращало те же 2 строки, и то же самое верно для всех других таблиц, возвращаемых запросом 1. Теперь планы выполнения показывают 3 шага ..
Как видите, поиск по индексу отсутствует, это просто сканирование таблицы, а
Top
показывает, что фактическое количество строк равно 2, как и Table Scan
; Но это не так (там много строк).
Но когда я запускаю что-то вроде
ВЫБРАТЬ ВЕРХ (2) *
ИЗ
MstConfigSettings
СОРТИРОВАТЬ ПО
DefaultItemId
План выполнения показывает
и
Итак, когда я не применяю ORDER BY
, шаги другие (сортировки нет). Но вопрос в том, как этот TOP
работает, когда нет Sort
и почему и как он всегда дает одинаковый результат?
Предложение
SQL Server ORDER BY на практических примерах
Резюме : в этом руководстве вы узнаете, как использовать предложение SQL Server ORDER BY
для сортировки набора результатов запроса по одному или нескольким столбцам.
Введение в SQL Server
Предложение ORDER BY
При использовании оператора SELECT
для запроса данных из таблицы порядок строк в наборе результатов не гарантируется. Это означает, что SQL Server может возвращать набор результатов с неопределенным порядком строк.
Единственный способ гарантировать, что строки в наборе результатов отсортированы, — это использовать предложение ORDER BY
. Ниже показан синтаксис предложения ORDER BY
:
Язык кода: SQL (язык структурированных запросов) (sql)
SELECT select_list ИЗ table_name СОРТИРОВАТЬ ПО
[ASC | DESC]
В этом синтаксисе:
имя_столбца
| выражение
Сначала вы указываете имя столбца или выражение, по которому нужно отсортировать набор результатов запроса.Если вы указываете несколько столбцов, набор результатов сортируется по первому столбцу, а затем этот отсортированный набор результатов сортируется по второму столбцу и так далее.
Столбцы, которые появляются в предложении ORDER BY
, должны соответствовать либо столбцу в списке выбора, либо столбцам, определенным в таблице, указанной в предложении FROM
.
ASC
| DESC
Во-вторых, используйте ASC
или DESC
, чтобы указать, следует ли отсортировать значения в указанном столбце в порядке возрастания или убывания.
ASC
сортирует результат от наименьшего значения к наибольшему, а DESC
сортирует набор результатов от наибольшего значения к наименьшему.
Если вы явно не укажете ASC
или DESC
, SQL Server использует ASC
в качестве порядка сортировки по умолчанию. Кроме того, SQL Server рассматривает NULL как самые низкие значения.
При обработке оператора SELECT
, содержащего предложение ORDER BY
, предложение ORDER BY
является самым последним для обработки.
SQL Server
Пример предложения ORDER BY
Мы будем использовать таблицу customers
в примере базы данных из демонстрации.
A) Сортировать набор результатов по одному столбцу в порядке возрастания
Следующий оператор сортирует список клиентов по имени в порядке возрастания:
Язык кода: SQL (язык структурированных запросов) (sql)
SELECT имя, фамилия ИЗ sales.customers СОРТИРОВАТЬ ПО имя;
В этом примере, поскольку мы не указали ASC
или DESC
, в предложении ORDER BY
по умолчанию используется ASC
.
B) Сортировка набора результатов по одному столбцу в порядке убывания
Следующая инструкция сортирует список клиентов по имени в порядке убывания.
Язык кода: SQL (язык структурированных запросов) (sql)
ВЫБРАТЬ имя, фамилия ИЗ sales.customers СОРТИРОВАТЬ ПО first_name DESC;
В этом примере, поскольку мы явно указали DESC
, предложение ORDER BY
отсортировало набор результатов по значениям в столбце first_name
в в порядке убывания.
C) Сортировка набора результатов по нескольким столбцам
Следующая инструкция извлекает имя, фамилию и город клиентов. Он сортирует список клиентов сначала по городу, а затем по имени.
Язык кода: SQL (язык структурированных запросов) (sql)
ВЫБРАТЬ Город, имя, фамилия ИЗ sales.customers СОРТИРОВАТЬ ПО Город, имя;
D) Сортировка набора результатов по нескольким столбцам и в разных порядках
Следующий оператор сортирует клиентов по городу в порядке убывания и сортировку отсортированный набор результатов по имени в порядке возрастания.
Язык кода: SQL (язык структурированных запросов) (sql)
ВЫБРАТЬ Город, имя, фамилия ИЗ sales.customers СОРТИРОВАТЬ ПО город DESC, first_name ASC;
E) Сортировка набора результатов по столбцу, которого нет в списке выбора
Можно отсортировать набор результатов по столбцу, в котором нет появятся в списке выбора. Например, следующий оператор сортирует клиентов по состоянию, даже если столбец состояние
не отображается в списке выбора.
Язык кода: SQL (язык структурированных запросов) (sql)
ВЫБРАТЬ Город, имя, фамилия ИЗ sales.customers СОРТИРОВАТЬ ПО штат;
Обратите внимание, что столбец состояния
определен в таблице клиентов
. Если бы это было не так, то у вас был бы неверный запрос.
F) Сортировка набора результатов по выражению
Функция LEN ()
возвращает количество символов в строке. Следующий оператор использует функцию LEN ()
в предложении ORDER BY
для получения списка клиентов, отсортированного по длине имени.
Язык кода: SQL (язык структурированных запросов) (sql)
ВЫБРАТЬ имя, фамилия ИЗ sales.customers СОРТИРОВАТЬ ПО LEN (имя) DESC;
G) Сортировка по порядковым номерам столбцов
SQL Server позволяет сортировать набор результатов на основе порядковых позиций столбцов, которые появляются в списке выбора .
Следующая инструкция сортирует клиентов по имени и фамилии. Но вместо того, чтобы явно указывать имена столбцов, он использует порядковые номера столбцов:
Язык кода: SQL (язык структурированных запросов) (sql)
SELECT имя, фамилия ИЗ продажи.клиенты СОРТИРОВАТЬ ПО 1, 2;
В этом примере 1 означает столбец first_name
, а 2 означает столбец last_name
.
Использование порядковых позиций столбцов в предложении ORDER BY
считается плохой практикой программирования по нескольким причинам.
- Во-первых, столбцы в таблице не имеют порядковых номеров, и на них нужно ссылаться по имени.
- Во-вторых, при изменении списка выбора вы можете забыть внести соответствующие изменения в предложение
ORDER BY
.
Поэтому рекомендуется всегда явно указывать имена столбцов в предложении ORDER BY
.
В этом руководстве вы узнали, как использовать предложение SQL Server ORDER BY
для сортировки набора результатов по столбцам в порядке возрастания или убывания.
Сортировка набора результатов на основе одного или нескольких столбцов
Сводка : В этом руководстве показано, как использовать предложение SQL ORDER BY
для сортировки набора результатов по указанным критериям в порядке возрастания или убывания.
Введение в SQL
Предложение ORDER BY
При использовании оператора SELECT
для запроса данных из таблицы порядок, в котором строки появляются в наборе результатов, может быть не таким, как вы ожидали.
В некоторых случаях строки, которые появляются в наборе результатов, находятся в том порядке, в котором они физически хранятся в таблице. Однако в случае, если оптимизатор запросов использует индекс для обработки запроса, строки будут отображаться в том порядке, в котором они хранятся в порядке ключей индекса.По этой причине порядок строк в наборе результатов не определен или непредсказуем.
Оптимизатор запросов — это встроенный в систему базы данных программный компонент, который определяет наиболее эффективный способ запроса запрошенных данных оператором SQL.
Чтобы точно указать порядок строк в наборе результатов, вы добавляете предложение use ORDER BY
в операторе SELECT
следующим образом:
Язык кода: SQL (язык структурированных запросов) (sql)
SELECT столбец1, столбец2 ИЗ table_name ЗАКАЗАТЬ ПО столбцу 1 ASC, column2 DESC;
В этом синтаксисе предложение ORDER BY
появляется после предложения FROM
.Если оператор SELECT
содержит предложение WHERE
, предложение ORDER BY
должно появиться после предложения WHERE
.
Чтобы отсортировать набор результатов, вы указываете столбец, в котором вы хотите выполнить сортировку, и тип порядка сортировки:
- По возрастанию (
ASC
) - По убыванию (
DESC
)
Если вы не t указать порядок сортировки, система базы данных обычно сортирует набор результатов в порядке возрастания ( ASC
) по умолчанию.
Когда вы включаете более одного столбца в предложение ORDER BY
, система базы данных сначала сортирует набор результатов на основе первого столбца, а затем сортирует отсортированный набор результатов на основе второго столбца и так далее.
SQL
Примеры предложений ORDER BY
Мы будем использовать таблицу сотрудников
в образце базы данных для демонстрации.
1) Использование предложения SQL
ORDER BY
для сортировки значений в одном столбце. Пример
Следующий оператор извлекает идентификатор сотрудника, имя, фамилию, дату найма и зарплату из таблицы сотрудников
:
Язык кода: SQL (язык структурированных запросов) (sql)
ВЫБРАТЬ employee_id, имя, фамилия, Дата приема на работу, зарплата ИЗ сотрудники;
Посмотрите в действии
Кажется, что строки отображаются так, как они хранятся в таблице сотрудников
.Чтобы отсортировать сотрудников по именам в алфавитном порядке, вы добавляете предложение ORDER BY
для запроса следующим образом:
Язык кода: SQL (язык структурированных запросов) (sql)
SELECT employee_id, имя, фамилия, Дата приема на работу, зарплата ИЗ сотрудники СОРТИРОВАТЬ ПО имя;
Посмотреть в действии
Теперь набор результатов отсортирован по столбцу first_name
.
2) Использование предложения SQL
ORDER BY
для сортировки значений в нескольких столбцах, пример
Для сортировки по сотрудникам по имени в возрастающем порядке и фамилии в порядке убывания используйте следующий оператор:
Язык кода: SQL (язык структурированных запросов) (sql)
ВЫБРАТЬ employee_id, имя, фамилия, Дата приема на работу, зарплата ИЗ сотрудники СОРТИРОВАТЬ ПО имя, last_name DESC;
Посмотреть в действии
Сначала система базы данных сортирует набор результатов по первому имени в возрастающем порядке, затем сортирует отсортированный набор результатов по фамилия в порядке убывания.Обратите внимание на изменение положения двух сотрудников: Alexander Khoo
и Alexander Hunold
3) Использование предложения SQL
ORDER BY
для сортировки значений в числовом столбце. Пример
SQL позволяет сортировать данные в алфавитном порядке, как показано на предыдущий пример, а также отсортировать данные численно. Например, следующий оператор выбирает данные о сотрудниках и сортирует набор результатов по заработной плате в порядке убывания:
Язык кода: SQL (язык структурированных запросов) (sql)
SELECT employee_id, имя, фамилия, Дата приема на работу, зарплата ИЗ сотрудники СОРТИРОВАТЬ ПО зарплата DESC;
Посмотрите в действии
4) Использование SQL
ORDER BY
для сортировки дат Пример
Помимо символов и чисел, SQL позволяет сортировать результат установлен по дате.Следующий оператор сортирует сотрудников по значениям в столбце найм_дата
в возрастающем порядке.
Язык кода: SQL (язык структурированных запросов) (sql)
ВЫБРАТЬ employee_id, имя, фамилия, Дата приема на работу, зарплата ИЗ сотрудники СОРТИРОВАТЬ ПО Дата приема на работу;
Посмотреть в действии
Для просмотра последних сотрудников, которые только что присоединились к компании, вы сортируете сотрудников по датам найма в убывающем порядке, как показано в следующем заявлении:
Язык кода: SQL (язык структурированных запросов) (sql)
SELECT employee_id, имя, фамилия, Дата приема на работу, зарплата ИЗ сотрудники СОРТИРОВАТЬ ПО Наем_дата DESC;
Посмотреть в действии
В этом руководстве вы узнали, как использовать предложение SQL ORDER BY
для сортировки набора результатов на основе одного или больше столбцов в порядке возрастания или убывания.
Было ли это руководство полезным?
ВЫБРАТЬ с ЗАКАЗОМ НА
Автор: Джереми Кадлец
Обзор
В этом руководстве мы выпустим различные операторы SELECT с предложениями ORDER BY, чтобы показать, как данные могут быть отсортированы как по возрастанию, так и по убыванию. Мы собираемся предложить примеры с символьными, числовыми и датированными столбцами. Мы также предоставим несколько примеров комбинаций этих столбцов и логики ORDER BY. Давайте посмотрим на пример.
Объяснение
В приведенных ниже примерах мы выбираем различные столбцы из таблицы HumanResources.Employee и упорядочиваем данные различными способами, чтобы показать различные параметры, доступные в SQL Server. В первом примере мы упорядочиваем данные по столбцу HireDate в возрастающем порядке. Во втором примере мы упорядочиваем данные по столбцу LoginID в порядке убывания. В третьем примере мы сначала упорядочиваем данные по столбцу LoginID в порядке возрастания, а затем по столбцу HireDate в порядке убывания.
Данные в порядке возрастания |
ЕГЭ AdventureWorks; ИДТИ ВЫБЕРИТЕ LoginID, EmployeeID, HireDate ОТ HumanResources.Employee ЗАКАЗАТЬ ПО HireDate ASC; ИДТИ |
Данные в порядке убывания |
ЕГЭ AdventureWorks; ИДТИ ВЫБЕРИТЕ LoginID, EmployeeID, HireDate ОТ HumanResources.Работник ЗАКАЗАТЬ ПО LoginID DESC; ИДТИ |
Столбец в порядке возрастания и отдельный столбец в порядке убывания |
ЕГЭ AdventureWorks; ИДТИ ВЫБЕРИТЕ LoginID, EmployeeID, HireDate ОТ HumanResources.Employee ЗАКАЗАТЬ ПО LoginID ASC, HireDate DESC; ИДТИ |
Последнее обновление: 25.03.2009
Оператор
Select без предложения Order By может не возвращать набор результатов в последовательности прибытия
SQL-операторы select, которые не содержат предложение order by , могут не возвращать набор результатов, упорядоченный по последовательности прибытия.Такое поведение разрешено спецификацией SQL. В спецификации указано: « Если порядок курсора не определяется предложением ORDER BY, относительное положение двух строк зависит от реализации ». Хотя спецификация SQL не гарантирует какого-либо упорядочения для этих типов операторов, более старые операционные системы выпускают возвращаемые наборы результатов для простых запросов в последовательности поступления. Начиная с V5R2, Db2 for i более широко использует функцию симметричной многопроцессорной обработки (SMP) (если она установлена).Такое поведение может привести к тому, что некоторые операторы select не имеют предложения order by, которое возвращает результаты в случайном порядке.
Приложения, использующие неуказанный порядок, могут завершиться ошибкой после обновления до V5R2. Проблема часто наблюдается в приложениях, которые используют SQL для возврата нереляционных данных. Например, некоторые приложения используют передачу данных или ODBC для возврата файлов, содержащих данные буферного файла или элементы исходного физического файла. Неупорядоченные данные могут повредить получившийся файл.Эти типы приложений необходимо изменить, чтобы указать порядок набора результатов.
Упорядочивание по последовательности поступления
Наборы результатов можно упорядочить по последовательности поступления (порядок хранения данных в файле) с помощью функции относительного числа записей (RRN). Чтобы изменить запрос так, чтобы он возвращал наборы результатов, упорядоченные, как в предыдущих выпусках, добавьте предложение order by rrn (fn) , где fn — имя файла, например: Выберите * из QIWS.Порядок QCUSTCDT по rrn (qiws.qcustcdt)
. Этот метод можно использовать только с операционной системой V5R2 и более поздних версий, поскольку поле order by отсутствует в наборе результатов.
Отключение функции SMP также может изменить порядок на более раннее поведение. Функцией SMP можно управлять с помощью системного значения QQRYDEGREE, команды CHGQRYA или настройки QAQQINI. Поскольку порядок наборов записей все еще не определен, этот метод не рекомендуется . Будущее обновление PTF или выпуска может изменить поведение.
Лексический и логический порядок предложения SELECT
Применимо к ✅ Open Source Edition ✅ Express Edition ✅ Professional Edition ✅ Enterprise Edition
SQL имеет лексический и логический порядок из предложений SELECT
. Лексический порядок предложений SELECT
вдохновлен английским языком. Поскольку операторы SQL являются командами для базы данных, естественно выразить оператор в императивном виде, например, «ВЫБЕРИТЕ то и то!».
Однако логический порядок предложений SELECT
не соответствует синтаксису. На самом деле логический порядок таков:
- Предложение FROM: во-первых, все источники данных определены и объединены
- Предложение WHERE: затем данные фильтруются как можно раньше
- Предложение CONNECT BY: затем данные просматриваются итеративно или рекурсивно для создания новых кортежей
- Предложение GROUP BY: Затем данные сокращаются до групп, возможно создание новых кортежей, если используются функции группирования, такие как ROLLUP (), CUBE (), GROUPING SETS ()
- Предложение HAVING: затем данные снова фильтруются
- Предложение SELECT: только сейчас выполняется оценка проекции.В случае оператора
SELECT DISTINCT
данные дополнительно сокращаются для удаления дубликатов - Предложение UNION: Необязательно, вышеуказанное повторяется для нескольких подзапросов, связанных
UNION
. Если это не предложениеUNION ALL
, данные дополнительно сокращаются для удаления дубликатов - Предложение ORDER BY: теперь все оставшиеся кортежи упорядочены в порядке
- Предложение LIMIT: Затем для упорядоченных кортежей создается представление с разбивкой на страницы
- Предложение FOR: преобразование в XML или JSON
- Предложение FOR UPDATE: наконец, применяется пессимистическая блокировка
Документация по SQL Server также объясняет это с немного другими предложениями:
-
ИЗ
-
ПО
-
ПРИСОЕДИНЯЙТЕСЬ
-
ГДЕ
-
ГРУППА ПО
-
С КУБОМ
илиС РОЛИКОМ
-
ИМЕЕТ
-
ВЫБРАТЬ
-
РАЗЛИЧНЫЙ
-
ЗАКАЗАТЬ В
-
ТОП
Как можно видеть, базы данных должны логически переупорядочить оператор SQL, чтобы определить лучший план выполнения.
Некоторые «высокоуровневые» абстракции, такие как LINQ в C # или SLICK в Scala, пытаются инвертировать лексический порядок предложений SELECT
к тому, что кажется более близким к логическому порядку. Очевидным преимуществом переноса предложения SELECT
в конец является тот факт, что тип проекции, который является типом записи, возвращаемой оператором SELECT
, может быть более легко повторно использован в целевой среде внутреннего языка, зависящего от домена. .
Пример LINQ:
// LINQ-to-SQL несколько похож на SQL // Предложение AS // Предложение FROM Из п В db.Products // Предложение WHERE Где p.UnitsInStock <= p.ReorderLevel AndAlso Not p. Discontinued // Предложение SELECT Выбрать p
// "for" - это "точка входа" в DSL val q = для { // Предложение FROM Предложение WHERE c <- Кофе, если c.supID === 101 // Предложение SELECT и проекция на кортеж } yield (c.наименование, ц.цена)
Хотя поначалу это кажется хорошей идеей, это только усложняет перевод в более сложные операторы SQL и ухудшает удобочитаемость для тех пользователей, которые привыкли писать SQL. jOOQ разработан так, чтобы выглядеть так же, как SQL. Это особенно верно для SLICK, который не только изменил порядок предложений SELECT
, но также сильно «интегрировал» предложения SQL с языком Scala.
По этим причинам API jOOQ DSL моделируется в лексическом порядке SQL.
Как упорядочить по двум столбцам в SQL?
Проблема:
Вам необходимо отобразить записи из данной таблицы, отсортированные по двум столбцам.
Пример:
В нашей базе данных есть таблица с именем employee
со следующими столбцами: id
, first_name
, last_name
и salary
.
id | имя | фамилия | зарплата |
---|---|---|---|
1 | Лиза | Ульман | 3000 |
2 | Ada | Muller | 2400 |
3 | Thomas | Зеленый | 2400 |
4 | Майкл | Мюллер | 3000 |
5 | Мэри | Зеленый | 2400 |
Давайте отобразим всю информацию для каждого сотрудника, но отсортируем записи сначала по заработной плате в порядке убывания, а затем по фамилии в порядке возрастания.
Решение:
ВЫБЕРИТЕ идентификатор, имя, фамилия, зарплата ОТ сотрудника ЗАКАЗАТЬ ПО зарплате DESC, last_name;
Этот запрос возвращает отсортированные записи по двум столбцам: salary и last_name .
id | имя | фамилия | зарплата |
---|---|---|---|
4 | Майкл | M uller | 3000 |
1 | Lisa | U lman | 3000 | 3 | Thomas | G reen | 2400 |
5 | Мэри | G reen | 2400 |
2 | Ada | M uller | 2400 |
Обсуждение:
Если вы хотите выбрать записи из таблицы, но хотите, чтобы они были отсортированы по двум столбцам, вы можете сделать это с помощью ORDER BY
.Это предложение находится в конце вашего SQL-запроса.
После ключевого слова ORDER BY
добавьте имя столбца, по которому вы хотите сначала отсортировать записи (в нашем примере - зарплата). Затем после запятой добавьте второй столбец (в нашем примере last_name
). Вы можете изменить порядок сортировки (по возрастанию или по убыванию) отдельно для каждого столбца. Если вы хотите использовать возрастающий (от меньшего к большему) порядок, вы можете использовать ключевое слово ASC
; это ключевое слово является необязательным, так как это порядок по умолчанию, когда ничего не указано.Если вы хотите использовать порядок убывания, поместите ключевое слово DESC
после соответствующего столбца (в этом примере мы использовали порядок убывания для столбца зарплата
).
В нашем примере мы сначала отсортировали результат по зарплате в порядке убывания (от более высоких зарплат к более низким), а затем по фамилии в порядке возрастания в уже отсортированных записях.