我有一个存储过程,它接收一个有序的ID列表,即('5,9,1,7,2')。简化程序,检查ID是否出现在表格中,然后按顺序输出这些ID:
CREATE PROCEDURE usp (`idlist` VARCHAR(255))
SELECT
@rank := @rank + 1 AS rank
id
FROM id_table t, (SELECT @rank := 0) s
WHERE FIND_IN_SET(t.id, idlist) > 0
但是,MySQL不会正确地订购这些ID。它将输出加扰为id顺序:
+-------+----+
| rank | id |
+-------+----+
| 1 | 1 |
| 2 | 2 |
| 3 | 5 |
| 4 | 7 |
| 5 | 9 |
+-------+----+
如果这是一次性案例,我可以简单地添加:
ORDER BY FIELD(id, '5', '9', '1', '7', '2')
获得所需的输出:
+-------+----+
| rank | id |
+-------+----+
| 1 | 5 |
| 2 | 9 |
| 3 | 1 |
| 4 | 7 |
| 5 | 2 |
+-------+----+
但是列表可以是任何不能“自然”排序的5个ID。所以我尝试了这个:
ORDER BY FIELD(id, CONCAT('"', REPLACE(idlist, ',', '","'), '"'));
将ID列表作为订单,但不起作用。如何让ORDER BY FIELD()收听idlist
中的订单?
(这与MYSQL - GROUP_CONCAT AND FIND_IN_SET are mixing values/order?有一些相似之处 - 但是这里的解决方案对我来说不起作用,可能是因为增加了@rank,存储过程参数,或者在实际的ORDER BY子句中使用了FIELD。 )
答案 0 :(得分:1)
只需添加:
ORDER BY FIND_IN_SET(t.id, idlist)
请勿使用field()
;使用find_in_set()
。