ПОРЯДОК По метке времени с нулями между будущим и прошлым

#mysql #sql #query-optimization

#mysql — сервер #sql #оптимизация запросов #mysql

Вопрос:

Я хотел бы упорядочить результаты SQL по полю метки времени в порядке убывания, сначала указав самые новые записи. Однако у меня есть определенные строки, которые являются пустыми или содержат нули. Как я могу распределить эти результаты между будущей и прошлой строками? Можно ли это сделать с помощью CASEs?

 SELECT * FROM table ORDER BY when DESC
  

РЕДАКТИРОВАТЬ: Спасибо всем ответам. Чтобы все знали, я выбрал MySQL IFNULL, т.Е.

 SELECT * FROM table ORDER BY IFNULL(when,UNIX_TIMESTAMP()) DESC
  

Это был самый простой подход, при котором if when содержал NULL, запрос select заменял его текущим временем unix. Обратите внимание, что я обновил свою базу данных и заменил все 0 значениями NULL.

Ответ №1:

Самая простая версия должна быть:

 SELECT *
FROM   mytable
ORDER  BY (mytime > now() AND mytime IS NOT NULL) DESC -- future times first
         ,(mytime IS NULL OR mytime = 0) DESC          -- NULL and "zero" next
         ,mytime DESC;                                 -- everything descending
  

Или еще проще с помощью инструкции CASE:

 SELECT *
FROM   mytable
ORDER  BY CASE WHEN mytime IS NULL OR mytime = 0 THEN now() ELSE mytime END DESC;
  

FALSE сортирует перед TRUE , поэтому нам нужно DESC сначала отсортировать попадания.
Прочитайте о специальном значении «Ноль» в MySQL в руководстве.

Комментарии:

1. Спасибо за то, что «ЛОЖНЫЕ сортировки перед ИСТИННЫМИ», «mytime РАВНО НУЛЮ» решили мою проблему 🙂

Ответ №2:

 SELECT   *
         , COALESCE(when, '2011-01-01 00:00:00') as new_when
FROM     table
ORDER BY new_when DESC
  

Подробнее о COALESCE() . В основном я использую 2011-01-01 00:00:00 в качестве метки времени по умолчанию, если она не установлена, поэтому любые элементы с null будут обрабатываться как эта дата. Мы называем эту дату как new_when и упорядочиваем по ней.

Комментарии:

1. Приятно, но два недостатка: не удается динамически обрабатывать «сейчас», не удается выполнить «ноль» в соответствии с запросом.

Ответ №3:

 SELECT * FROM TABLE IF(mytime is null, [sometime],mytime) ORDER BY ...
  

Не уверен на 100%, является ли код ‘is null’, но я сделал что-то подобное.

Комментарии:

1. Итак, в основном, если это NULL (или ноль, или что-то еще) Я должен назначить ему текущее время … которое поместило бы его в середину с помощью простой сортировки по убыванию.

2. IS NULL правильно. Затем вы можете заменить [sometime] на NOW() , чтобы использовать текущее время.

3. @user984512, обновление значений в таблице (и будущих значений путем установки значения по умолчанию и т.д.) Отличается от установки нулей между прошлым и будущим.

Ответ №4:

Я не уверен, работает ли этот синтаксис, но я думаю, что это идея…

 ORDER BY
    CASE WHEN mytime IS NOT NULL AND mytime > NOW() THEN 'a'
         WHEN mytime IS NULL THEN 'b'
         WHEN mytime IS NOT NULL AND mytime < NOW() THEN 'c'
    END
    , mytime