按SQL IN()子句中的值顺序排序

Dar*_*ein 144 mysql sql sql-order-by

我想知道是否存在(可能更好的方式)按IN()子句中的值的顺序排序.

问题是我有2个查询,一个获取所有ID,第二个查询所有信息.第一个创建我想要第二个订购的ID的顺序.ID以正确的顺序放入IN()子句中.

所以它就像(非常简化):

SELECT id FROM table1 WHERE ... ORDER BY display_order, name

SELECT name, description, ... WHERE id IN ([id's from first])
Run Code Online (Sandbox Code Playgroud)

问题是第二个查询不会按照将ID放入IN()子句的顺序返回结果.

我发现的一个解决方案是将所有ID放入具有自动递增字段的临时表中,然后将该字段连接到第二个查询中.

有更好的选择吗?

注意:由于第一个查询是"由用户"运行而第二个查询是在后台进程中运行,因此无法使用子查询将2到1的查询组合在一起.

我正在使用MySQL,但我认为让它注意到其他数据库的选项可能也很有用.

ʞɔı*_*ɔıu 177

使用MySQL的FIELD()功能:

SELECT name, description, ...
FROM ...
WHERE id IN([ids, any order])
ORDER BY FIELD(id, [ids in order])
Run Code Online (Sandbox Code Playgroud)

FIELD() 将返回第一个参数的索引,该索引等于第一个参数(第一个参数本身除外).

FIELD('a', 'a', 'b', 'c')

将返回1

FIELD('a', 'c', 'b', 'a')

将返回3

如果将id粘贴到IN()子句中并且FIELD()函数以相同的顺序粘贴,这将完全符合您的要求.

  • 这不是太慢吗? (5认同)
  • 你能在Oracle中做到这一点吗? (4认同)
  • 根据定义,@Vojto按任意顺序排序很慢.这是最好的,因为不能保证`IN`和`FIELD`参数相等.通过使用该附加知识,在程序代码中执行此操作可能会更快.当然,如果您考虑到服务器性能,将这种负担放在客户端而不是服务器上可能更明智. (3认同)
  • “sqlite”呢? (3认同)

小智 14

请参阅以下如何获取排序数据.

SELECT ...
  FROM ...
 WHERE zip IN (91709,92886,92807,...,91356)
   AND user.status=1
ORDER 
    BY provider.package_id DESC 
     , FIELD(zip,91709,92886,92807,...,91356)
LIMIT 10
Run Code Online (Sandbox Code Playgroud)


Joh*_*son 11

我想到两种解决方案:

  1. order by case id when 123 then 1 when 456 then 2 else null end asc

  2. order by instr(','||id||',',',123,456,') asc

(instr()是Oracle;也许你有locate()charindex()或类似的东西)


小智 6

SELECT ORDER_NO, DELIVERY_ADDRESS 
from IFSAPP.PURCHASE_ORDER_TAB 
where ORDER_NO in ('52000077','52000079','52000167','52000297','52000204','52000409','52000126') 
ORDER BY instr('52000077,52000079,52000167,52000297,52000204,52000409,52000126',ORDER_NO)
Run Code Online (Sandbox Code Playgroud)

工作得非常好


Ian*_*Ian 6

如果您想使用MS SQL Server 2008+中的查询输入的值对查询进行任意排序,可以通过动态创建表并执行类似的连接(使用OP中的命名法)来完成.

SELECT table1.name, table1.description ... 
FROM (VALUES (id1,1), (id2,2), (id3,3) ...) AS orderTbl(orderKey, orderIdx) 
LEFT JOIN table1 ON orderTbl.orderKey=table1.id
ORDER BY orderTbl.orderIdx
Run Code Online (Sandbox Code Playgroud)

如果将VALUES语句替换为执行相同操作的其他语句,但在ANSI SQL中,则这应该适用于任何SQL数据库.

注意: 查询大于100的记录集时,创建的表(orderTbl.orderIdx)中的第二列是必需的.我最初没有orderIdx列,但发现结果集大于100我必须按该列显式排序; 无论如何,在SQL Server Express 2014中.

  • @Darryl,它不会.但是当你谷歌如何通过IN子句订购时,这篇文章出现了最高结果,所以我想我也可以在这里发布它,一般方法适用于所有ANSI兼容的SQL服务器(只需用标准替换VALUES语句)创建表的方法). (2认同)

Gul*_*ati 5

Ans获取排序数据.

SELECT ...
FROM ...
ORDER  BY FIELD(user_id,5,3,2,...,50)  LIMIT 10
Run Code Online (Sandbox Code Playgroud)