Keep order from 'IN' clause

后端 未结 5 1404
花落未央
花落未央 2020-12-11 00:23

Is it possible to keep order from a \'IN\' conditional clause?

I found this question on SO but in his example the OP have already a sorted \'IN\' clause.

My

相关标签:
5条回答
  • 2020-12-11 00:58

    There will be no reliable ordering unless you use an ORDER BY clause ..

    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
    

    You could split the query into 5 queries union all'd together though ...

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

    I'd trust the former method more, and it would probably perform much better.

    0 讨论(0)
  • 2020-12-11 00:59

    There is an alternative that uses string functions:

    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))||',')
    

    I offer this because you might find it easier to maintain a string of values rather than an intermediate table.

    0 讨论(0)
  • 2020-12-11 01:00

    Try this:

    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
    
    0 讨论(0)
  • 2020-12-11 01:07

    Decode function comes handy in this case instead of case expressions:

    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)
    

    Note that value,position pairs (e.g. 445,3) are kept together for readability reasons.

    0 讨论(0)
  • 2020-12-11 01:09

    I was able to do this in my application using (using 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 ')
    

    I used a code-side regex to replace \b (word boundary) with a space. Something like...

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

    Importantly, because I can in my scenario, I cache the result until the next time the related items are updated, so that the query is only run at item creation/modification, rather than with each item viewing, helping to minimize any performance hit.

    0 讨论(0)
提交回复
热议问题