Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

วิธีรักษาลำดับ SELECT ใน MySQL UNION ด้วย ORDER BY CASE

จัดเรียงผลลัพธ์ UNION ตามลำดับที่ต้องการด้วย CASE WHEN

คำสั่ง UNION จะจัดเรียงผลลัพธ์อัตโนมัติ (และลบแถวซ้ำ) ทำให้ลำดับเดิมของแต่ละ SELECT หายไป แก้ไขได้โดยใช้ ORDER BY CASE แทน UNION

ตัวอย่างสร้างตารางและข้อมูล

CREATE TABLE DemoTable (
    Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ShippingDate DATETIME
);

INSERT INTO DemoTable (ShippingDate) VALUES
('2019-04-21'), ('2019-01-01'), ('2019-05-11'),
('2018-12-31'), ('2019-02-18');

ข้อมูลในตาราง

+----+---------------------+
| Id | ShippingDate        |
+----+---------------------+
| 1  | 2019-04-21 00:00:00 |
| 2  | 2019-01-01 00:00:00 |
| 3  | 2019-05-11 00:00:00 |
| 4  | 2018-12-31 00:00:00 |
| 5  | 2019-02-18 00:00:00 |
+----+---------------------+

คำสั่งจัดเรียง: วันที่อนาคต (>= วันนี้) ก่อน เรียงจากใหม่ไปเก่า, วันที่ผ่านมา (< วันนี้) ทีหลัง เรียงจากใหม่ไปเก่า

SELECT * FROM DemoTable
ORDER BY CASE 
    WHEN ShippingDate < CURDATE() THEN ShippingDate 
    ELSE CURDATE() 
END DESC, ShippingDate ASC;

ผลลัพธ์ (สมมติวันนี้คือ 2019-06-04)

+----+---------------------+
| Id | ShippingDate        |
+----+---------------------+
| 3  | 2019-05-11 00:00:00 |
| 1  | 2019-04-21 00:00:00 |
| 5  | 2019-02-18 00:00:00 |
| 2  | 2019-01-01 00:00:00 |
| 4  | 2018-12-31 00:00:00 |
+----+---------------------+

คำอธิบาย:

  • CASE WHEN ShippingDate < CURDATE() THEN ShippingDate ELSE CURDATE() END: แยกเป็น 2 กลุ่ม: วันที่ผ่านมา (ค่า = วันที่จริง) และวันที่อนาคต (ค่า = วันนี้ = ค่าคงที่)
  • DESC: เรียงค่า CASE จากมากไปน้อย → วันที่อนาคต (CURDATE()) จะมากกว่าวันที่ผ่านมา → กลุ่มอนาคตอยู่บน
  • ShippingDate ASC: จัดเรียงรองภายในกลุ่มเดียวกันจากเก่าไปใหม่

เทคนิคนี้เหมาะกับ: การแสดงรายการ "กำลังจะมาถึง" ก่อน แล้วค่อย "ที่ผ่านมาแล้ว" ทั้งในคิวรี่เดียว ไม่ต้อง UNION