เรียงลำดับตามค่าฟิลด์เฉพาะก่อน


93

ฉันมีตารางที่มี 3 คอลัมน์:

id | name | priority
--------------------
 1 | core  |   10
 2 | core  |   9
 3 | other |   8
 4 | board |   7
 5 | board |   6
 6 | core  |   4

ฉันต้องการจัดลำดับชุดผลลัพธ์โดยใช้priorityแต่ก่อนอื่นแถวที่มีname=coreลำดับความสำคัญต่ำกว่า ผลลัพธ์ควรมีลักษณะดังนี้

id | name | priority
--------------------
 6 | core  |   4
 2 | core  |   9
 1 | core  |   10
 5 | board |   6
 4 | board |   7
 3 | other |   8

คำตอบ:


161

นอกจากนี้ยังมีMySQLFIELDฟังก์ชั่น

หากคุณต้องการเรียงลำดับอย่างสมบูรณ์สำหรับค่าที่เป็นไปได้ทั้งหมด:

SELECT id, name, priority
FROM mytable
ORDER BY FIELD(name, "core", "board", "other")

หากคุณสนใจเพียงว่า "แกน" เป็นอันดับแรกและค่าอื่น ๆ ก็ไม่สำคัญ:

SELECT id, name, priority
FROM mytable
ORDER BY FIELD(name, "core") DESC

หากคุณต้องการจัดเรียงตาม "หลัก" ก่อนและช่องอื่น ๆ ตามลำดับการจัดเรียงปกติ:

SELECT id, name, priority
FROM mytable
ORDER BY FIELD(name, "core") DESC, priority

มีข้อแม้บางประการที่นี่แม้ว่า:

อันดับแรกฉันค่อนข้างมั่นใจว่านี่เป็นฟังก์ชัน mysql เท่านั้น - คำถามนี้ติดแท็ก mysql แต่คุณไม่มีทางรู้

ประการที่สองให้ความสนใจกับวิธีการFIELD()ทำงาน: จะส่งคืนดัชนีฐานเดียวของค่า - ในกรณีFIELD(priority, "core")นี้จะส่งคืน 1 หาก "core" เป็นค่า ถ้าค่าของฟิลด์ไม่ได้อยู่ในรายการก็จะส่งกลับศูนย์ นี่คือเหตุผลที่DESCจำเป็นเว้นแต่คุณจะระบุค่าที่เป็นไปได้ทั้งหมด


5
หลังจากผ่านไปประมาณ 5 ปีฉันได้เปลี่ยนคำตอบที่ยอมรับนี้เพราะมันสะอาดและเร็วขึ้น
Omid

เทียบเท่า db2?
Cybermonk

มันได้ผลสำหรับฉันอยากจะถามอีกคำถามหนึ่งเกี่ยวกับวิธีจัดการถ้าคอลัมน์ 'ลำดับความสำคัญ' มีค่าเช่น 'เอิร์ ธ คอร์', 'บอร์ดใหม่' เป็นต้นที่นี่คอลัมน์ไม่มีค่าที่แน่นอนเราสามารถเขียนสิ่งที่ต้องการได้ไหม % แกน%?
Jayanth Suwana

@JayanthSuvarna: ดูที่เอกสาร MySQL FIELD () ฉันค่อนข้างแน่ใจว่าไม่มีวิธีใดที่จะประเมินสิ่งนี้เป็นสตริงย่อยได้เนื่องจากแต่ละอาร์กิวเมนต์ต้องเป็นสตริงบางประเภท อาจมีฟังก์ชั่นการจัดการสตริงบางอย่างที่ช่วยได้ แต่ฉันไม่แน่ใจ
Nerdmaster

ขอบคุณเพื่อน คุณทำให้วันของฉัน
BEingprabhU

93

โดยทั่วไปคุณสามารถทำได้

select * from your_table
order by case when name = 'core' then 1 else 2 end,
         priority 

โดยเฉพาะใน MySQL คุณสามารถทำได้

select * from your_table
order by name <> 'core',
         priority 

เนื่องจากผลลัพธ์ของการเปรียบเทียบใน MySQL เป็นอย่างใดอย่างหนึ่ง 0หรือ1และคุณสามารถจัดเรียงตามผลลัพธ์นั้นได้


1
สิ่งที่ไม่1และ2วิธีการที่นี่?
Niraj Chauhan

1
ฉันจัดเรียงแถวได้ประมาณ 3000 แถว ในกรณีของฉันการแก้ปัญหาของ @ Ayman-Hourieh บนstackoverflow.com/questions/958627/…ใช้เวลาครึ่งหนึ่งเมื่อเทียบกับโซลูชันนี้
nightlyop

@nightlyop: ดีครับ หมายเหตุเพียงข้อเดียว: โซลูชันที่เร็วกว่าคือเฉพาะ MySQL
juergen d

1และ 2เป็นเพียงตัวเลข 2 ตัวที่ฉันใช้ในการจัดเรียงข้อมูล อาจเป็น3และ4หรืออย่างอื่น
juergen d

แล้วเมื่อมีอยู่%ในWHEREข้อ? ชอบ. . . WHERE name LIKE '%sth%' . . .? stackoverflow.com/questions/41303379/…
stack

6

วิธีหนึ่งในการให้ความสำคัญกับแถวที่เจาะจงคือการเพิ่มจำนวนมากให้กับลำดับความสำคัญ คุณสามารถทำได้ด้วยCASEคำสั่ง:

  select id, name, priority
    from mytable
order by priority + CASE WHEN name='core' THEN 1000 ELSE 0 END desc

การสาธิต: http://www.sqlfiddle.com/#!2/753ee/1


5

สิ่งนี้ใช้ได้กับฉันโดยใช้ Postgres 9+:

SELECT *
FROM your_table
ORDER BY name = 'core' DESC, priority DESC

สนใจที่จะอธิบาย -1? ข้อผิดพลาด + เวอร์ชัน Postgres?
Vojtech Vitek

3

ทางเดียวคือ:

select id, name, priority from table a
order by case when name='core' then -1 else priority end asc, priority asc

1
สิ่งนี้จะไม่เสียลำดับของcoreแถวหรือไม่?
mellamokb

1
SELECT * FROM cars_new WHERE status = '1' and car_hide !='1' and cname IN ('Executive Car','Saloon','MPV+','MPV5') ORDER BY FIELD(cname, 'Executive Car', 'Saloon','MPV+','mpv5')

3
แม้ว่ารหัสของคุณอาจเป็นคำตอบสำหรับคำถาม แต่ก็ควรให้คำอธิบายเกี่ยวกับเรื่องนี้ดีกว่า
Mehraban

0

ทำเช่นนี้:

SELECT * FROM table ORDER BY column `name`+0 ASC

การต่อท้าย +0 จะหมายความว่า:

0, 10, 11, 2, 3, 4

กลายเป็น :

0, 2, 3, 4, 10, 11

เทคนิคนี้ใช้สำหรับเปลี่ยนสตริงให้เป็นตัวเลข ไม่ได้ตอบคำถามของ OP (อย่างไรก็ตามหากไม่เห็นประเภทข้อมูลpriorityฉันไม่สามารถบอกได้ว่าควรเป็นส่วนหนึ่งของโซลูชันที่สมบูรณ์หรือไม่)
Rick James

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.