MySQL 按列中的一个特定值排序(具有逗号分隔值)

MySQL ORDER By one Specific value in column (having comma separated values)

我想根据城市(从下拉列表中选择)对用户记录进行排序。就像如果我在我的查询中传递 city_id 22 那么我希望所有的行首先具有 city_ids 22 然后是其余的行。

我知道 WHERE find_in_set('22',city_ids) 会给我正确的结果,但它不会 return 所有行,所以我想使用一些 ORDER BY 来实现它。

我已经尝试 ORDER BY FIND_IN_SET('22',city_ids) 但它不起作用。我该如何解决这个问题,有什么最好的方法吗?

用户Table:

Id    Name     city_ids
1     AAAAA    10,22,30
2     BBBBB    11,28
3     CCCCC    15,22,44
4     DDDDD    19,99,
5     EEEEE    55,27,22

想要如下所示的排序输出:

Id    Name     city_ids
1     AAAAA    10,22,30
3     CCCCC    15,22,44
5     EEEEE    55,27,22
2     BBBBB    11,28
4     DDDDD    19,99,

你可以这样做:

ORDER BY (FIND_IN_SET('22', city_ids) > 0) DESC

这会将匹配放在首位。

那么你应该修复你的数据模型。它坏了,坏了,坏了。出于多种原因,将 ID 列表存储在字符串中是错误的:

  • 数据类型(大概)是错误的。 ID 是数字,不应存储为字符串。
  • 在一列中存储多个值并不是 SQL 的存储方式。
  • ID 应正确声明外键关系,但您无法声明。
  • SQL没有很好的字符串处理函数
  • 生成的查询无法利用索引或分区,影响性能。
  • SQL 拥有用于存储事物列表的非常棒的数据结构。它被称为 table,而不是字符串列。

表达式:

FIND_IN_SET('22', city_ids) > 0

将 return 1 用于 city_ids 列中存在 '22' 的所有行,而 0 用于其他行。
因此,之后您需要再添加一个级别以按 id 升序排序:

ORDER BY 
  FIND_IN_SET('22', city_ids) > 0 DESC, 
  id 

参见demo
结果:

| Id  | Name  | city_ids |
| --- | ----- | -------- |
| 1   | AAAAA | 10,22,30 |
| 3   | CCCCC | 15,22,44 |
| 5   | EEEEE | 55,27,22 |
| 2   | BBBBB | 11,28    |
| 4   | DDDDD | 19,99    |