Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL-基于查询参数保留排序_Sql_Oracle - Fatal编程技术网

SQL-基于查询参数保留排序

SQL-基于查询参数保留排序,sql,oracle,Sql,Oracle,我正在尝试使用IN子句执行选择,我希望能够以与我列表中IN元素相同的顺序返回结果。例如: SELECT * FROM orders WHERE order_no IN ('B123', 'B483', 'B100', 'B932', ...); 我希望他们以同样的顺序回来。理想情况下,如果我能有这样的陈述,那就太好了: SELECT * FROM orders WHERE order_no IN ('B123', 'B483', 'B100', 'B932', ...) ORDER BY ('

我正在尝试使用
IN
子句执行
选择
,我希望能够以与我列表中
IN
元素相同的顺序返回结果。例如:

SELECT * FROM orders WHERE order_no IN ('B123', 'B483', 'B100', 'B932', ...);
我希望他们以同样的顺序回来。理想情况下,如果我能有这样的陈述,那就太好了:

SELECT * FROM orders WHERE order_no IN ('B123', 'B483', 'B100', 'B932', ...)
ORDER BY ('B123', 'B483', 'B100', 'B932', ...);

我见过使用或关键字定义某种自定义排序的查询示例。但是,在所有这些例子中,它们的顺序都是针对一组预先确定的选项。然而,我的排序完全取决于我的用户输入的搜索条件,因此可能有一个包含2个选项的列表或一个包含100个选项的列表来排序


有什么想法吗?一些我不知道的Oracle功能,或者使用
大小写
解码
进行动态设置的方法?

将值插入临时表,并将您的选择加入到该表中

然后可以对临时表列执行自然顺序

CREATE GLOBAL TEMPORARY TABLE sort_table (
  value       VARCHAR2(100),
  sort_order  NUMBER
) ON COMMIT DELETE ROWS;

INSERT INTO sort_table VALUES ('B123',1);
INSERT INTO sort_table VALUES ('B483',2);
... etc. ...

select * from mytable
inner join sort_table
on mytable.mycolumn = sort_table.value
order by sort_table.sort_order;

要清除临时表,只需
COMMIT

我不是Python高手,但下面是我在PHP中的实现方法,希望您能理解

  • 构建如下所示的字符串:

    $str=“('B123','B483','B100','B932',…)”

    对于以上内容,您可以使用For循环或其他方法来构建一个非常长的字符串

  • 在查询中插入字符串,如下所示:


  • 正如我所说,这是一个PHP示例,但我相信您已经明白了。

    我不知道是否有一个优雅(或简短)的解决方案

    如果可以动态生成查询,则以下操作应该可以正常工作:

    WITH numbers AS (
       SELECT 1 as sort_order, 'B123' as order_no FROM DUAL
       union all
       SELECT 2 as sort_order, 'B483' as order_no FROM DUAL
       union all
       SELECT 2 as sort_order, 'B100' as order_no FROM DUAL
       union all
       SELECT 2 as sort_order, 'B932' as order_no FROM DUAL
    )
    SELECT orders.*
    FROM numbers  
      LEFT JOIN orders ON orders.ord_no = numbers.ord_no
    ORDER BY numbers.sort_order
    

    您可以像下面这样通过instr连接变量和顺序。我不能保证这样做的效率——但必须是好的。显然,您的前端需要做更多的工作。但是构建这样的查询可能会对sql注入开放

    SELECT * FROM orders WHERE order_no IN ('B123', 'B483', 'B100', 'B932', ...)
    ORDER BY 
      instr ('@B123@'|| '@B483@'||'@B100@'||'@B932@'||... ,'@'|| order_no||'@')
    

    如果要使用DECODE指定数字排序顺序:

    SELECT ID FROM tbl WHERE ID IN (2,3,1)
    ORDER BY DECODE(ID, 2, 1, 3, 2, 3)
    

    我在最近的一个问题中作了回答


    我的答案使用了管道行函数,因此它不需要像这里接受的答案那样使用临时表。

    您可以尝试一下,它可以正常工作。检查以下sql:-

    SELECT * FROM orders WHERE order_no IN ('B123', 'B483', 'B100', 'B932') 
    ORDER BY DECODE(order_no,'B123','1','B483','2','B100','3','B932','4');
    

    在MySQL中,您可以按字段('ORDER_no','B123','B483','B100'…)进行
    排序,但我不知道是否有与Oracle等效的。按解码排序(ORDER_no',B123',1',B483',2',B100',3,…,1000)
    如何?显然,您必须构建正确的
    DECODE
    子句。您使用的是什么数据库?我认为,
    orderby
    不支持这样的元素列表:-\即使在理论上,我也看不出这在任何SQL实现中可能起到什么作用。您的思路是正确的,但您需要第二列来保存序列号并按序列号排序。我更喜欢使用
    decode(…)
    构造的答案。使用语句规则+1Nice方法-适用于短值的小列表。适用于高达9英寸的解码,而不是更多。如果有更多信息,则只有第一个值是正确的(Oracle Database 11g 11.2.0.4.0版-64位生产)
    SELECT * FROM orders WHERE order_no IN ('B123', 'B483', 'B100', 'B932') 
    ORDER BY DECODE(order_no,'B123','1','B483','2','B100','3','B932','4');