Mysql заказ по определенным значениям идентификатора


96

Можно ли сортировать в mysql по «порядку по», используя предопределенный набор значений столбца (ID), например: порядок по (ID = 1,5,4,3), чтобы я получил запись 1, 5, 4, 3 в этом заказать?

ОБНОВЛЕНИЕ: о злоупотреблении mysql ;-) Я должен объяснить, зачем мне это нужно ...

Я хочу, чтобы мои записи менялись случайным образом каждые 5 минут. У меня есть задача cron, чтобы сделать таблицу обновлений, чтобы поместить в нее другой случайный порядок сортировки. Есть только одна проблема! СТРАНИЦА. У меня будет посетитель, который зайдет на мою страницу, и я дам ему первые 20 результатов. Он подождет 6 минут и перейдет на страницу 2, и у него будут неправильные результаты, поскольку порядок сортировки уже изменился.

Поэтому я подумал, что если он зайдет на мой сайт, я помещу все идентификаторы в сеанс, и когда он будет на странице 2, он получит правильные записи, даже если сортировка уже изменилась.

Есть ли другой способ лучше сделать это?


Вы спрашиваете, есть ли способ, которым mysql может упорядочивать без определенного порядка?
stefgosselin

1
Похоже, либо ваша модель данных сломана / неполна ( откуда этот порядок?), Либо вы злоупотребляете MySQL.
derobert

Ответы:


204

Вы можете использовать функции ORDER BY и FIELD. См. Http://lists.mysql.com/mysql/209784

SELECT * FROM table ORDER BY FIELD(ID,1,5,4,3)

Он использует функцию Field () , которая "возвращает индекс (позицию) str в списке str1, str2, str3, .... Возвращает 0, если str не найдена" согласно документации. Фактически вы сортируете набор результатов по возвращаемому значению этой функции, которое является индексом значения поля в данном наборе.


Кажется, я не могу заставить это работать, не используя: WHERE ID IN (1,5,4,3)
TV-C-15

1
как бы вы использовали это со значениями None?
Ноно Лондон,

30

Вы должны уметь использовать CASEдля этого:

ORDER BY CASE id
  WHEN 1 THEN 1
  WHEN 5 THEN 2
  WHEN 4 THEN 3
  WHEN 3 THEN 4
  ELSE 5
END

18

В официальной документации для mysql о ORDER BY кто-то опубликовал, что вы можете использовать FIELDдля этого, например:

SELECT * FROM table ORDER BY FIELD(id,1,5,4,3)

Это непроверенный код, который теоретически должен работать.


7
SELECT * FROM table ORDER BY id='8' DESC, id='5' DESC, id='4' DESC, id='3' DESC

Например, если у меня было 10 реестров, таким образом сначала появятся идентификаторы 1, 5, 4 и 3, а затем появятся другие реестры.

Обычная выставка 1 2 3 4 5 6 7 8 9 10

Таким образом

8 5 4 3 1 2 6 7 9 10


Хорошо, спасибо за совет
Бруно Манджини Алвес

6

Есть другой способ решить эту проблему. Добавьте отдельную таблицу, примерно так:

CREATE TABLE `new_order` (
  `my_order` BIGINT(20) UNSIGNED NOT NULL,
  `my_number` BIGINT(20) NOT NULL,
  PRIMARY KEY (`my_order`),
  UNIQUE KEY `my_number` (`my_number`)
) ENGINE=INNODB;

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

Добавьте туда свои значения:

my_order | my_number
---------+----------
       1 |         1
       2 |         5
       3 |         4
       4 |         3

... а затем измените свой оператор SQL при присоединении к этой новой таблице.

SELECT *
FROM your_table AS T1
INNER JOIN new_order AS T2 on T1.id = T2.my_number
WHERE ....whatever...
ORDER BY T2.my_order; 

Это решение немного сложнее, чем другие решения, но с его помощью вам не нужно менять свое SELECT-запись при изменении критериев вашего заказа - просто измените данные в таблице заказов.


1

Если вам нужно сначала заказать в результате один идентификатор, используйте идентификатор.

select id,name 
from products
order by case when id=5 then -1 else id end

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

select id,name 
from products
order by case when id in (30,20,10) then -1 else id end,id

Добавьте еще описание
Мэтьюз Санни

если вы хотите использовать заказ только для одного идентификатора, используйте 1-й запрос, а если вы хотите использовать несколько идентификаторов, используйте 2-й запрос
Раджеш Харатмол

0

Если вы хотите, чтобы один идентификатор был последним в результате, используйте порядок по регистру. (Например: вы хотите, чтобы в последнем списке отображался вариант «Другой», а весь список городов отображался в алфавитном порядке.)

select id,city 
from city
order by case 
when id = 2 then city else -1 
end, city ASC

Например, если у меня было 5 городов, я хочу показать город в алфавитном порядке с последним отображением опции «другой» в раскрывающемся списке, тогда мы можем использовать этот запрос. см. пример, другие показаны в моей таблице по второму идентификатору (id: 2), поэтому я использую «when id = 2» в приведенном выше запросе.

запись в таблице БД:

Bangalore - id:1
Other     - id:2
Mumbai    - id:3
Pune      - id:4
Ambala    - id:5

мой вывод:

Ambala  
Bangalore  
Mumbai  
Pune
Other

2
Попробуйте добавить в свой код пояснения, это сделает ваш ответ более ясным и понятным. Прочтите stackoverflow.com/help/how-to-answer
32cupo

если вы хотите использовать порядок по только для одного идентификатора (например: вы хотите, чтобы в последнем списке отображалась опция «другой», а весь список городов отображался в алфавитном порядке.), вы можете использовать этот запрос. это работает для меня.
Preeti

-1
SELECT * FROM TABLE ORDER BY (columnname,1,2) ASC OR DESC

2
Вы можете объяснить это дальше? Это похоже на принятый ответ, но я не думаю, что ASC OR DESCэто правильный синтаксис
Нико Хаасе

@NicoHaase, разница между ASC и DESC в том, что если вы используете asc, то идентификаторы, которые вы используете в функции поля, будут в конце, а если вы используете DESC, тогда идентификаторы в функции поля будут первыми
Хишам шахид

@NicoHaase, вы можете использовать ASC или DESC с запросом, который соответствует требованиям
Хишам шахид

Таким образом, вы не можете использовать оба в одном запросе. Нико, я думаю, предлагал, чтобы вы ответили синтаксически правильно. Я почти уверен, что он знает, что на самом деле означают ASD и DESC :)
RiggsFolly

В этом нет смысла и точно не получится. Вам необходимо использовать FIELDфункцию, которая идентична принятому ответу за 8 лет до этого.
хакель
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.