oracle 从'IN'子句保留顺序

xoefb8l8  于 2022-12-22  发布在  Oracle
关注(0)|答案(6)|浏览(193)

有可能从'IN'条件子句中保持顺序吗?
我在SO上找到了this question,但在他的示例中,OP已经有了一个排序的“IN”子句。
我的情况不同,'IN'子句的顺序是随机的类似这样:

SELECT SomeField,OtherField
FROM TestResult 
WHERE TestResult.SomeField IN (45,2,445,12,789)

我想按(45,2,445,12,789)顺序检索结果。我使用的是Oracle数据库。也许SQL中有一个属性可以用于条件子句,以指定保持子句的顺序。

ifmq2ha2

ifmq2ha21#

除非使用ORDER BY子句,否则将没有可靠的排序。

SELECT SomeField,OtherField
FROM TestResult 
WHERE TestResult.SomeField IN (45,2,445,12,789)
order by case TestResult.SomeField
         when 45 then 1
         when 2  then 2
         when 445 then 3
         ...
         end

您可以将查询拆分为5个查询,然后将它们合并在一起...

SELECT SomeField,OtherField
FROM TestResult 
WHERE TestResult.SomeField = 4
union all
SELECT SomeField,OtherField
FROM TestResult 
WHERE TestResult.SomeField = 2
union all
...

我更信任前一种方法,它可能会执行得更好。

py49o6xq

py49o6xq2#

在这种情况下,*Decode函数 * 比 *case表达式 * 更方便:

SELECT SomeField,OtherField
FROM TestResult 
WHERE TestResult.SomeField IN (45,2,445,12,789)
ORDER BY DECODE(SomeField, 45,1, 2,2, 445,3, 12,4, 789,5)

注意,* 值,位置 * 对(例如 * 445,3 *)出于可读性原因而保持在一起。

vx6bjr1n

vx6bjr1n3#

试试这个:

SELECT T.SomeField,T.OtherField
FROM TestResult T
 JOIN 
   (
     SELECT 1 as Id, 45 as Val FROM dual UNION ALL
     SELECT 2, 2 FROM dual UNION ALL
     SELECT 3, 445 FROM dual UNION ALL
     SELECT 4, 12 FROM dual UNION ALL
     SELECT 5, 789  FROM dual
   ) I
   ON T.SomeField = I.Val
ORDER BY I.Id
pw136qt2

pw136qt24#

还有一种使用字符串函数的替代方法:

with const as (select ',45,2,445,12,789,' as vals)
select tr.*
from TestResult tr cross join const
where instr(const.vals, ','||cast(tr.somefield as varchar(255))||',') > 0
order by instr(const.vals, ','||cast(tr.somefield as varchar(255))||',')

我之所以提供这种方法,是因为您可能会发现维护一个值字符串比维护一个中间表更容易。

q5lcpyga

q5lcpyga5#

我能够在我的应用程序中使用(使用SQL Server 2016)完成此操作

select ItemID, iName
  from Items
      where ItemID in (13,11,12,1)
      order by CHARINDEX(' ' + Convert("varchar",ItemID) + ' ',' 13 , 11 , 12 , 1 ')

我使用了一个代码端正则表达式,用一个空格替换了\b(单词边界)。

var mylist = "13,11,12,1";
var spacedlist = replace(mylist,/\b/," ");

重要的是,因为我可以在我的场景中缓存结果,直到下一次更新相关项,所以查询只在创建/修改项时运行,而不是在查看每个项时运行,这有助于最大限度地减少性能损失。

2nc8po8w

2nc8po8w6#

通过集合(SYS.ODCINUMBERLIST是内置集合的一个示例)传入值,然后按集合的顺序对行进行排序:

SELECT t.SomeField,
       t.OtherField
FROM   TestResult t
       INNER JOIN (
         SELECT ROWNUM AS rn,
                COLUMN_VALUE AS value
         FROM   TABLE(SYS.ODCINUMBERLIST(45,2,445,12,789))
       ) i
       ON t.somefield = i.value
ORDER BY rn

然后,对于样本数据:

CREATE TABLE TestResult ( somefield, otherfield ) AS
SELECT   2, 'A' FROM DUAL UNION ALL
SELECT   5, 'B' FROM DUAL UNION ALL
SELECT  12, 'C' FROM DUAL UNION ALL
SELECT  37, 'D' FROM DUAL UNION ALL
SELECT  45, 'E' FROM DUAL UNION ALL
SELECT 100, 'F' FROM DUAL UNION ALL
SELECT 445, 'G' FROM DUAL UNION ALL
SELECT 789, 'H' FROM DUAL UNION ALL
SELECT 999, 'I' FROM DUAL;

输出为:
| 索梅菲尔德|其他领域|
| - ------|- ------|
| 四十五|E级|
| 第二章|A类|
| 四百四十五|G级|
| 十二|C级|
| 七八九|高|
fiddle

相关问题