Порядок Mysql за конкретними значеннями ідентифікатора


95

Чи можна сортувати в mysql за "упорядкувати за", використовуючи заздалегідь визначений набір значень стовпців (ID), наприклад: упорядкувати за (ID = 1,5,4,3), щоб я отримав запис 1, 5, 4, 3 у цьому замовити?

ОНОВЛЕННЯ: Про зловживання mysql ;-) Я повинен пояснити, навіщо мені це потрібно ...

Я хочу, щоб мої записи сортувались випадково кожні 5 хвилин. У мене є завдання cron - зробити таблицю оновлення, щоб додати в неї інший, довільний порядок сортування. Є лише одна проблема! ПАГІНАЦІЯ. У мене буде відвідувач, який зайде на мою сторінку, і я даю йому перші 20 результатів. Він почекає 6 хвилин і перейде на сторінку 2, і у нього будуть неправильні результати, оскільки порядок сортування вже змінився.

Тож я подумав, що якщо він заходить на мій сайт, я поміщаю всі посвідчення особи на сеанс, і коли він перебуває на сторінці 2, він отримує правильні записи, навіть якщо сортування вже змінено.

Чи є інший спосіб, краще, зробити це?


Ви запитуєте, чи існує спосіб, який MySQL може замовити в певному порядку?
stefgosselin

1
Здається, або ваша модель даних порушена / неповна ( звідки це замовлення?), Або ви зловживаєте MySQL.
derobert

Відповіді:


202

Ви можете використовувати функцію 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

як би ви використали це зі значеннями 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 реєстрів, таким чином ID 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-заяву щоразу, коли змінюються критерії замовлення - просто змініть дані в таблиці замовлень.


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

2
Ви можете пояснити це далі? Це схоже на прийняту відповідь, але я не думаю, що ASC OR DESCце правильний синтаксис
Ніко Хаасе,

@NicoHaase різниця між ASC та DESC полягає в тому, що якщо ви використовуєте asc, то ідентифікатори, які ви використовуєте у польовій функції, закінчаться, а якщо ви використовуєте DESC, тоді ідентифікатори у польовій функції будуть першими
Hisham

@NicoHaase, ви можете використовувати або ASC, або DESC із запитом, який відповідає вимогам
Hisham

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

0

Якщо вам потрібно спочатку замовити один ідентифікатор у результаті, використовуйте ідентифікатор.

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), тому я використовую "коли 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

якщо ви хочете використовувати порядок лише для одного ідентифікатора (Наприклад: ви хочете в останньому варіанті "інший", а всі списки міст відображатимуться в алфавітному порядку.), щоб ви могли використовувати цей запит. це працює для мене.
Преті
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.