Order by select: Предложение ORDER BY (Transact-SQL) — SQL Server

Содержание

ORDER BY | Документация ClickHouse

  1. Справка по SQL
  2. Выражения
  3. 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.

SingerAlbumYearSale
The ProdigyInvaders Must Die20081200000
Drowning PoolSinner2001400000
Massive AttackMezzanine19982300000
The ProdigyFat of the Land1997600000
The ProdigyMusic For The Jilted Generation19941500000
Massive Attack100th Window20031200000
Drowning PoolFull Circle2007800000
Massive AttackDanny The Dog20041900000
Drowning PoolResilience2013500000

Пример 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
Совершеннолетние пользователи
idlast_namefirst_namebirthday
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 хранит строки, то сортировка происходит в алфавитном порядке:

Сортировка по фамилии
idlast_namefirst_namebirthday
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

Теперь таблица отсортирована сразу по двум поля, сперва по фамилии, а уже затем по имени:

Сортировка по фамилии и имени
idlast_namefirst_namebirthday
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

И получить данные упорядоченные по дате рождения в хронологическом порядке:

Сортировка по дате рождения
idlast_namefirst_namebirthday
6ИвановАлексей1993-08-05
4ИвановаСветлана1993-08-06
1ИвановДмитрий1996-12-11
7ПроцукАлена1997-02-28
3ШевченкоТимур1998-04-27

А если в конструкции ORDER BY после имени столца написать DESC, то данные будут отсортированы в обратном порядке — свежие даты выше:

Сортировка по дате рождения в обратном порядке
idlast_namefirst_namebirthday
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

Тогда данные будут сперва отсортированы в алфавитном порядке по фамилии, а уже внутри каждой фамилии по дате рождения в обратном порядке:

Сортировка по дате рождения в обратном порядке
idlast_namefirst_namebirthday
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 :

 

SELECT select_list ИЗ table_name СОРТИРОВАТЬ ПО

Язык кода: SQL (язык структурированных запросов) (sql)

[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) Сортировать набор результатов по одному столбцу в порядке возрастания

Следующий оператор сортирует список клиентов по имени в порядке возрастания:

 

SELECT имя, фамилия ИЗ sales.customers СОРТИРОВАТЬ ПО имя;

Язык кода: SQL (язык структурированных запросов) (sql)

В этом примере, поскольку мы не указали ASC или DESC , в предложении ORDER BY по умолчанию используется ASC .

B) Сортировка набора результатов по одному столбцу в порядке убывания

Следующая инструкция сортирует список клиентов по имени в порядке убывания.

 

ВЫБРАТЬ имя, фамилия ИЗ sales.customers СОРТИРОВАТЬ ПО first_name DESC;

Язык кода: SQL (язык структурированных запросов) (sql)

В этом примере, поскольку мы явно указали DESC , предложение ORDER BY отсортировало набор результатов по значениям в столбце first_name в в порядке убывания.

C) Сортировка набора результатов по нескольким столбцам

Следующая инструкция извлекает имя, фамилию и город клиентов. Он сортирует список клиентов сначала по городу, а затем по имени.

 

ВЫБРАТЬ Город, имя, фамилия ИЗ sales.customers СОРТИРОВАТЬ ПО Город, имя;

Язык кода: SQL (язык структурированных запросов) (sql)

D) Сортировка набора результатов по нескольким столбцам и в разных порядках

Следующий оператор сортирует клиентов по городу в порядке убывания и сортировку отсортированный набор результатов по имени в порядке возрастания.

 

ВЫБРАТЬ Город, имя, фамилия ИЗ sales.customers СОРТИРОВАТЬ ПО город DESC, first_name ASC;

Язык кода: SQL (язык структурированных запросов) (sql)

E) Сортировка набора результатов по столбцу, которого нет в списке выбора

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

 

ВЫБРАТЬ Город, имя, фамилия ИЗ sales.customers СОРТИРОВАТЬ ПО штат;

Язык кода: SQL (язык структурированных запросов) (sql)

Обратите внимание, что столбец состояния определен в таблице клиентов . Если бы это было не так, то у вас был бы неверный запрос.

F) Сортировка набора результатов по выражению

Функция LEN () возвращает количество символов в строке. Следующий оператор использует функцию LEN () в предложении ORDER BY для получения списка клиентов, отсортированного по длине имени.

 

ВЫБРАТЬ имя, фамилия ИЗ sales.customers СОРТИРОВАТЬ ПО LEN (имя) DESC;

Язык кода: SQL (язык структурированных запросов) (sql)

G) Сортировка по порядковым номерам столбцов

SQL Server позволяет сортировать набор результатов на основе порядковых позиций столбцов, которые появляются в списке выбора .

Следующая инструкция сортирует клиентов по имени и фамилии. Но вместо того, чтобы явно указывать имена столбцов, он использует порядковые номера столбцов:

 

SELECT имя, фамилия ИЗ продажи.клиенты СОРТИРОВАТЬ ПО 1, 2;

Язык кода: SQL (язык структурированных запросов) (sql)

В этом примере 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 следующим образом:

 

SELECT столбец1, столбец2 ИЗ table_name ЗАКАЗАТЬ ПО столбцу 1 ASC, column2 DESC;

Язык кода: SQL (язык структурированных запросов) (sql)

В этом синтаксисе предложение ORDER BY появляется после предложения FROM .Если оператор SELECT содержит предложение WHERE , предложение ORDER BY должно появиться после предложения WHERE .

Чтобы отсортировать набор результатов, вы указываете столбец, в котором вы хотите выполнить сортировку, и тип порядка сортировки:

  • По возрастанию ( ASC )
  • По убыванию ( DESC )

Если вы не t указать порядок сортировки, система базы данных обычно сортирует набор результатов в порядке возрастания ( ASC ) по умолчанию.

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

SQL

Примеры предложений ORDER BY

Мы будем использовать таблицу сотрудников в образце базы данных для демонстрации.

1) Использование предложения SQL

ORDER BY для сортировки значений в одном столбце. Пример

Следующий оператор извлекает идентификатор сотрудника, имя, фамилию, дату найма и зарплату из таблицы сотрудников :

 

ВЫБРАТЬ employee_id, имя, фамилия, Дата приема на работу, зарплата ИЗ сотрудники;

Язык кода: SQL (язык структурированных запросов) (sql)

Посмотрите в действии

Кажется, что строки отображаются так, как они хранятся в таблице сотрудников .Чтобы отсортировать сотрудников по именам в алфавитном порядке, вы добавляете предложение ORDER BY для запроса следующим образом:

 

SELECT employee_id, имя, фамилия, Дата приема на работу, зарплата ИЗ сотрудники СОРТИРОВАТЬ ПО имя;

Язык кода: SQL (язык структурированных запросов) (sql)

Посмотреть в действии

Теперь набор результатов отсортирован по столбцу first_name .

2) Использование предложения SQL

ORDER BY для сортировки значений в нескольких столбцах, пример

Для сортировки по сотрудникам по имени в возрастающем порядке и фамилии в порядке убывания используйте следующий оператор:

 

ВЫБРАТЬ employee_id, имя, фамилия, Дата приема на работу, зарплата ИЗ сотрудники СОРТИРОВАТЬ ПО имя, last_name DESC;

Язык кода: SQL (язык структурированных запросов) (sql)

Посмотреть в действии

Сначала система базы данных сортирует набор результатов по первому имени в возрастающем порядке, затем сортирует отсортированный набор результатов по фамилия в порядке убывания.Обратите внимание на изменение положения двух сотрудников: Alexander Khoo и Alexander Hunold

3) Использование предложения SQL

ORDER BY для сортировки значений в числовом столбце. Пример

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

 

SELECT employee_id, имя, фамилия, Дата приема на работу, зарплата ИЗ сотрудники СОРТИРОВАТЬ ПО зарплата DESC;

Язык кода: SQL (язык структурированных запросов) (sql)

Посмотрите в действии

4) Использование SQL

ORDER BY для сортировки дат Пример

Помимо символов и чисел, SQL позволяет сортировать результат установлен по дате.Следующий оператор сортирует сотрудников по значениям в столбце найм_дата в возрастающем порядке.

 

ВЫБРАТЬ employee_id, имя, фамилия, Дата приема на работу, зарплата ИЗ сотрудники СОРТИРОВАТЬ ПО Дата приема на работу;

Язык кода: SQL (язык структурированных запросов) (sql)

Посмотреть в действии

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

 

SELECT employee_id, имя, фамилия, Дата приема на работу, зарплата ИЗ сотрудники СОРТИРОВАТЬ ПО Наем_дата DESC;

Язык кода: SQL (язык структурированных запросов) (sql)

Посмотреть в действии

В этом руководстве вы узнали, как использовать предложение 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 после соответствующего столбца (в этом примере мы использовали порядок убывания для столбца зарплата ).

В нашем примере мы сначала отсортировали результат по зарплате в порядке убывания (от более высоких зарплат к более низким), а затем по фамилии в порядке возрастания в уже отсортированных записях.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *