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

Задача
Вы хотите выполнить сортировку по дню календарного года.

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

Обсуждение
Сортировка в календарном порядке отличается от сортировки по дате. Вы не учитываете год и сортируете только по месяцу и дню, чтобы понять, как даты распределены по календарному году. Предположим, что у вас есть таблица event, которая выглядит следующим образом, если даты расположены в хронологическом порядке:

mysql> SELECT date, description FROM event ORDER BY date;

+--------------+----------------------------------------+
| date | description |
+--------------+----------------------------------------+
| 1215-06-15 | Signing of the Magna Carta |
| 1732-02-22 | George Washington's birthday |
| 1776-07-14 | Bastille Day |
| 1789-07-04 | US Independence Day |
| 1809-02-12 | Abraham Lincoln's birthday |
| 1919-06-28 | Signing of the Treaty of Versailles |
| 1944-06-06 | D-Day at Normandy Beaches |
| 1957-10-04 | Sputnik launch date |
| 1958-01-31 | Explorer 1 launch date |
| 1989-11-09 | Opening of the Berlin Wall |
+--------------+----------------------------------------+

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

mysql> SELECT date, description FROM event
-> ORDER BY MONTH(date), DAYOFMONTH(date);

+------------+-------------------------------------+
| date | description |
+--------------+----------------------------------------+
| 1958-01-31 | Explorer 1 launch date |
| 1809-02-12 | Abraham Lincoln's birthday |
| 1732-02-22 | George Washington's birthday |
| 1944-06-06 | D-Day at Normandy Beaches |
| 1215-06-15 | Signing of the Magna Carta |
| 1919-06-28 | Signing of the Treaty of Versailles |
| 1789-07-04 | US Independence Day |
| 1776-07-14 | Bastille Day |
| 1957-10-04 | Sputnik launch date |
| 1989-11-09 | Opening of the Berlin Wall |
+--------------+-----------------------------------------+

MySQL включает в себя функцию DAYOFYEAR(), которая может быть полезна для упорядочивания по календарному дню:mysql> SELECT date, description FROM event ORDER BY DAYOFYEAR(date);

+--------------+----------------------------------------+
| date | description |
+--------------+----------------------------------------+
| 1958-01-31 | Explorer 1 launch date |
| 1809-02-12 | Abraham Lincoln's birthday |
| 1732-02-22 | George Washington's birthday |
| 1944-06-06 | D-Day at Normandy Beaches |
| 1215-06-15 | Signing of the Magna Carta |
| 1919-06-28 | Signing of the Treaty of Versailles |
| 1789-07-04 | US Independence Day |
| 1776-07-14 | Bastille Day |
| 1957-10-04 | Sputnik launch date |
| 1989-11-09 | Opening of the Berlin Wall |
+--------------+----------------------------------------+

Кажется, что все хорошо, но это лишь потому, что в таблице нет записей,
представляющих трудности для обработки посредством DAYOFYEAR(): функ-
ция может выдавать одно значение для разных календарных дней.


Напри-
мер, 29 февраля високосного года и 1 марта невисокосного года будут счи-
таться одним и тем же днем:

mysql> SELECT DAYOFYEAR('1996-02-29'), DAYOFYEAR('1997-03-01');

+--------------------------------+---------------------------------+
| DAYOFYEAR('1996-02-29') | DAYOFYEAR('1997-03-01') |
+--------------------------------+---------------------------------+
| 60 | 60 |
+--------------------------------+---------------------------------+

Такая особенность функции DAYOFYEAR() означает, что результаты календарной сортировки, выполненной с ее помощью, не всегда будут корректными. Она может сгруппировать вместе даты, на самом деле являющиеся разными календарными днями.

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

mysql> SELECT lastname, firstname, birthyear, birthmonth, birthday
-> FROM master;

+------------------+-----------+------------+-------------+-----------+
| lastname | firstname | birthyear | birthmonth | birthday |
+-----------------+------------+------------+-------------+-----------+
| AARON | HANK | 1934 | 2 | 5 |
| AARON | TOMMIE | 1939 | 8 | 5 |
| AASE | DON | 1954 | 9 | 8 |
| ABAD | ANDY | 1972 | 8 | 25 |
| ABADIE | JOHN | 1854 | 11 | 4 |
| ABBATICCHIO | ED | 1877 | 4 | 15 |
| ABBEY | BERT | 1869 | 11 | 29 |
| ABBEY | CHARLIE | 1866 | 10 | 14 |

Чтобы упорядочить записи в календарном порядке, используем столбцы birthmonth и birthday.


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

mysql> SELECT lastname, firstname, birthyear, birthmonth, birthday
-> FROM master
-> WHERE birthmonth IS NOT NULL AND birthday IS NOT NULL
-> ORDER BY birthmonth, birthday, lastname, firstname;

+------------------+-----------+------------+-------------+-----------+
| lastname | firstname | birthyear | birthmonth | birthday |
+-----------------+------------+------------+-------------+-----------+
| ALLEN | ETHAN | 1904 | 1 | 1 |
| BEIRNE | KEVIN | 1974 | 1 | 1 |
| BELL | RUDY | 1881 | 1 | 1 |
| BERTHRONG | HARRY | 1844 | 1 | 1 |
| BETHEA | BILL | 1942 | 1 | 1 |
| BISHOP | CHARLIE | 1924 | 1 | 1 |
| BOBB | RANDY | 1948 | 1 | 1 |
| BRUCKMILLER | ANDY | 1882 | 1 | 1 |
...
Для больших наборов данных сортировка по отдельным столбцам составляющих даты может оказаться гораздо быстрее сортировки, извлекающей эти составляющие из значений DATE.


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



Оцените статью: (0 голосов)
0 5 0

Статьи из раздела MySQL на эту тему:
Использование ORDER BY для сортировки результатов запроса
Размещение некоторых значений в начале или конце упорядоченного списка
Сортировка IP-адресов в числовом порядке
Сортировка в порядке, определенном пользователем
Сортировка значений ENUM