Есть ли в mysql функциональность для заказа по определенной строке? - PullRequest
0 голосов
/ 02 января 2019

У меня есть таблица, например, студенты:

 id | name
 -- |-----
 1  | A
 2  | B
 3  | C
 4  | D
 5  | E
 6  | F
 7  | G
 8  | H`

Как создать sql в mysql, чтобы первые 4 студента были упорядочены по возрастанию идентификатора, а порядок отдыха по убыванию идентификатора должен выглядеть примерно так

id |  name
---|------
1  | A
2  | B
3  | C
4  | D
8  | H
7  | G
6  | F
5  | E

Ответы [ 3 ]

0 голосов
/ 02 января 2019

Вы можете использовать коррелированный подзапрос, чтобы вычислить «ранг» строки.Сортировка тривиальна:

SELECT *, (SELECT COUNT(*) FROM t AS x WHERE id < t.id) AS rn
FROM t
ORDER BY CASE WHEN rn >= 4 THEN -rn END, rn
  • SELECT COUNT(*) FROM t AS x WHERE id < t.id присваивает последовательные номера каждой строке, начиная с 0
  • CASE WHEN rn >= 4 THEN -rn END, присваивает NULL рангу 0 ... 3, поэтому вторичная сортировкатребуется.
0 голосов
/ 02 января 2019

Основываясь на ваших данных выборки, самый простой метод будет:

order by (case when id <= 4 then 1 else 2 end),
         (case when id <= 4 then id end),
         name desc;

Если вы не знаете, где находится четвертый идентификатор, тогда:

select s.*
from students s cross join
     (select s2.id
      from students s2
      order by s2.id
      limit 3, 1
     ) as s4
order by (case when s.id <= s4.id then 1 else 2 end),
         (case when s.id <= s4.id then s.id end),
         s.name desc;
0 голосов
/ 02 января 2019

Вы используете версию MySQL ранее, чем 8+, что означает, что вы не можете использовать аналитические функции здесь. Вот один из способов сделать это, используя коррелированный подзапрос с выражением CASE:

SELECT t1.id, t1.name
FROM yourTable t1
ORDER BY
    CASE WHEN (SELECT COUNT(*) FROM yourTable t2 WHERE t2.id <= t1.id) <= 4
         THEN 0
         ELSE 1 END,
    CASE WHEN (SELECT COUNT(*) FROM yourTable t2 WHERE t2.id <= t1.id) <= 4
         THEN id
         ELSE -id END;

enter image description here

Демо

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

Обратите внимание, что аналитические функции значительно упрощают чтение кода. Вот что вы можете сделать с MySQL 8 +:

SELECT t1.id, t1.name
FROM yourTable t1
ORDER BY
    CASE WHEN ROW_NUMBER() OVER (ORDER BY id) <= 4 THEN 0 ELSE 1 END,
    CASE WHEN ROW_NUMBER() OVER (ORDER BY id) <= 4 THEN id ELSE -id END;
...