如何让sql查询出来的数据的排序是按照id在in()列表中的顺序来排序显示呢?
比如 : select * from tab where id in (1, 9, 3, 4, 8, 5, 6);
要按照 1,9,3,4,8,5,6 的顺序显示数据。
乍一看, 蒙圈了。 其本质 ,是按照 id 在列表中的位置来排序。 知道了这个问题的根本就好办了。
网上 有现成的 mysql , oracle , sqlserver 的方法。
mysql写法:
SELECT * FROM EVENT WHERE eventId IN(443,419,431,440,420,414,509) ORDER BY INSTR(’,443,419,431,440,420,414,509,’,CONCAT(’,’,eventId,’,’))
oracle写法:
select name from order where oderid in(111,222,333,444,555,666)order by instr(‘111,222,333,444,555,666’,orderid)
sqlserver写法:
Select * From Product Where id in (1,1588,15782,9887,54) Order By charindex(’,’+ id +’,’, ‘,1,1588,15782,9887,54,’)
那么PG 数据库的方法呢?
发现pg 真是太牛逼。 我至少能写出 5种方法。
-
select * from tab s(id) where id in (17,19,142867, 33) order by position(id::text in ‘17,19,142867, 33’) ;
-
select * from tab where id in (17,19,142867, 33) order by position(’,’||id ::text||’,’ in ‘,’|| ‘17,19,142867, 33’||’,’ ) ;
-
select * from tab where id in (17,19,142867, 33) order by array_positions(array[17,19,142867, 33],id ) ;
-
select * from tab s(id) where id in (17,19,142867, 33) order by array_positions(‘{17,19,142867, 33}:: array[], id ) ;
-
select * from tab where id = any(array[ 17,19,142867, 33]) order by array_positions(‘{17,19,142867, 33}:: array[], id ) ;
前面两种 是基于字符串的构建, 效率上有些慢。
下面的基于 数值型 数组的方法 ,效率快很多。
PostgreSQL
select * from userinfo where name in ('Mark','Teddy','David','PaulD') order by array_positions(array['Mark','Teddy','David','PaulD'],name ::text);
select * from userinfo where name in (‘Mark’,‘Teddy’,‘David’,‘PaulD’) order by position(’,’||name ::text||’,’ in ‘,’|| array_to_string(Array[‘Mark’,‘Teddy’,‘David’,‘PaulD’],’,’) ||’,’);