Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

SELECT ... IN() không sắp xếp kết quả trong MySQL - dùng FIND_IN_SET

Mệnh đề IN() trong MySQL **không bảo đảm thứ tự** kết quả theo danh sách giá trị. Để giữ thứ tự, dùng ORDER BY FIND_IN_SET().

Ví dụ minh họa

Tạo bảng sản phẩm:

mysql> CREATE TABLE ProductStock (
    -> ProductId INT,
    -> ProductName VARCHAR(20),
    -> ProductQuantity INT,
    -> ProductPrice FLOAT
    -> );

mysql> INSERT INTO ProductStock VALUES(1, 'Product-101', 10, 500.56);
mysql> INSERT INTO ProductStock VALUES(25, 'Product-111', 5, 150.00);
mysql> INSERT INTO ProductStock VALUES(67, 'Product-311', 7, 1000.50);
mysql> INSERT INTO ProductStock VALUES(55, 'Product-561', 8, 900.00);
mysql> INSERT INTO ProductStock VALUES(75, 'Product-221', 15, 670.56);

Dữ liệu:

+-----------+-------------+-----------------+--------------+
| ProductId | ProductName | ProductQuantity | ProductPrice |
+-----------+-------------+-----------------+--------------+
|         1 | Product-101 |              10 |       500.56 |
|        25 | Product-111 |               5 |        150   |
|        67 | Product-311 |               7 |       1000.5 |
|        55 | Product-561 |               8 |        900   |
|        75 | Product-221 |              15 |       670.56 |
+-----------+-------------+-----------------+--------------+

Vấn đề: IN() sắp xếp theo ProductId mặc định

mysql> SELECT * FROM ProductStock WHERE ProductId IN (25,55,67,75,1);

Kết quả sẽ theo thứ tự 1, 25, 55, 67, 75 (sắp xếp số tăng).

Giải pháp: ORDER BY FIND_IN_SET()

mysql> SELECT * FROM ProductStock 
    -> WHERE ProductId IN (25,55,67,75,1) 
    -> ORDER BY FIND_IN_SET(ProductId, '25,55,67,75,1');

Kết quả theo đúng thứ tự mong muốn:

+-----------+-------------+-----------------+--------------+
| ProductId | ProductName | ProductQuantity | ProductPrice |
+-----------+-------------+-----------------+--------------+
|        25 | Product-111 |               5 |        150   |
|        55 | Product-561 |               8 |        900   |
|        67 | Product-311 |               7 |       1000.5 |
|        75 | Product-221 |              15 |       670.56 |
|         1 | Product-101 |              10 |       500.56 |
+-----------+-------------+-----------------+--------------+

Giải thích FIND_IN_SET

  • FIND_IN_SET(str, strlist): Trả về vị trí (1-based) của str trong chuỗi danh sách strlist
  • Danh sách phải không có khoảng trắng: '25,55,67,75,1'
  • Trả về 0 nếu không tìm thấy (hàng không trong IN sẽ lên đầu nếu không có WHERE)

Lưu ý: FIND_IN_SET không dùng index, chậm trên bảng lớn. Với dữ liệu lớn, cân nhắc JOIN với bảng tạm hoặc derived table có cột sort_order.