MySQL: сначала упорядочить по определенным элементам, затем по времени

#mysql #sql #mysql-8.0

#mysql #sql #mysql-8.0

Вопрос:

Допустим, у нас есть таблица

 names
-------------------
id     name      created_at
1      alpha     2020-10-23 17:30:35
2      beta      2020-10-24 17:30:35
3      gamma     2020-10-25 17:30:35
4      kilo      2020-10-26 17:30:35
5      charlie   2020-10-27 17:30:35
6      hector    2020-10-28 17:30:35
  

Я хочу упорядочить первые несколько строк по фиксированному массиву, скажем 6,3,2 , а остальные created_at — в порядке убывания.
Итак, порядок, который я ожидаю, будет 6,3,2,5,4,1 следующим.

Как я могу добиться этого с помощью Mysql?

Я попытался использовать field(), но не могу заставить его работать с другим столбцом.

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

1. Просто используйте FIELD()

Ответ №1:

FIELD() для этого сложно, потому что он возвращает 0 , если совпадений нет. Вы можете создать выражение, которое делает то, что вы хотите:

 order by coalesce(nullif(field(id, 6, 3, 2), 0), 999999),
         created_at desc
  

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

 order by (case when id in (6, 3, 2) then id end) desc,
         created_at desc
  

Ответ №2:

 SELECT * FROM names ORDER BY (
CASE
    WHEN id = 6 THEN 1
    WHEN id = 3 THEN 2
    WHEN id = 2 THEN 3
    ELSE 4
END, created_at DESC
)
  

CASE Оператор гарантирует, что первые 3 перечисленных элемента равны 6, 3 и 2, а остальные перечислены по created_at DESC порядку.

Ответ №3:

Одним из вариантов было бы написать выражение case следующим образом

   select *
    from names
order by case when id in (6,3,2) then 0
              else 1
          end asc,created_at desc
  

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

1. Я не голосовал против, но вопрос кажется довольно ясным, что 6/3/2 фиксировано в их порядке, а не упорядочено по дате создания (хотя данные неоднозначны в этом вопросе).).

2. интересно, что на основе данных в том виде, в каком они существуют сейчас, вы можете найти результаты этого запроса 6,3,2, за которыми следует 5,4,1. Также я предположил, что для каждого инкрементного идентификатора дата-время будет увеличиваться. Вот мой полный тестовый пример dbfiddle.uk /…

3. Я не понизил голос, но я также подозревал, что этот ответ был неправильным, потому что упорядочение по 0, когда идентификатор находится в (6,3,2), означает, что эти три записи будут упорядочены created_at DESC . Теперь, из-за дат этих записей, это просто запрошенный порядок OP, но если даты когда-либо изменятся, они больше не будут извлекаться в порядке 6,3,2. Другими словами, если вы хотите гарантировать порядок 6,3,2, вы должны явно указать это в ORDER BY предложении, как я сделал в своем ответе.