2012-09-21 33 views
2

我有一个表MY_TABLE,主键为MY_PK。然后,我有一个有序的主键列表,例如(17,13,35,2,9)。如何在Oracle/SQL中以给定顺序检索行?

现在我想用这些主键检索所有行,并按照给定键的列表相同的方式保持行的顺序。

我initally做什么:

SELECT * FROM MY_TABLE WHERE MY_PK IN (:my_list) 

但随后返回行的顺序是随机的,不符合给定键的顺序了。有没有办法实现这一点? 我唯一想到的是生成许多SELECT语句并将它们与UNION连接起来,但我的主键列表可能非常长,并且包含数百甚至数千个键。我想到的另一种方法是在应用程序中对行进行重新排序,但我宁愿选择不需要的解决方案。

回答

1

确保您的结果集上的订单的方法是使用ORDER BY,所以我会做的是插入一个2列的临时表中您的主键和一个secuencial ID,您将在稍后使用以创建ORDER BY 。您态表将是:

PrimaryKey ID 
------------------- 
17   1 
13   2 
35   3 
2    4 
9    5 

之后只使用一个连接你的表上的PrimaryKey列,为了你的时态表的ID列的态表的。

2

首先,这样做与工会不一定会有所帮助。除非您有order by子句,否则结果集中行的排序不保证

这里是一个解决方案,虽然这是不好的:

with keys as (
    select 1 as ordering, 17 as pk from dual union all 
    select 2 as ordering, 13 as pk from dual union all 
    select 3 as ordering, 35 as pk from dual union all 
    select 4 as ordering, 2 as pk from dual union all 
    select 5 as ordering, 9 as pk from dual 
    ) 
select mt.* 
from My_Table mt join 
    keys 
    on mt.my_pk = keys.pk 
order by keys.ordering 
2

仅Oracle 保证如果有一个明确的ORDER BY语句排序的结果集的顺序。所以你真正的问题是,“我如何保证把我的结果排序为任意顺序?”

那么简单的答案是你不能。更复杂的答案是您需要将您的任意顺序与可以排序的索引关联起来。

我会假设你得到你的ID列表作为一个字符串。 (如果你将它们作为一个数组或类似的东西类似于桌子般的生活更容易。)所以首先你需要标记你的字符串。在我的例子中,我使用this other SO threadsplitter函数。我将在公用表表达式中使用它来获取一些行,并使用rownum伪列来合成索引。然后我们将CTE输出加入您的表格。

with cte as 
    (select s.column_value as id 
      , rownum as sort_order 
     from table(select splitter('17,13,35,2,9') from dual) s 
    ) 
select yt.* 
from your_table yt 
where yt.id = cte.id 
order by cte.sort_order 

警告:这是未经测试的代码,但原则是健全的。如果确实遇到无法解决的编译或语法错误,请在评论中包含足够的详细信息。

+0

Oracle,没有,没有RDBMS我知道将保证结果的排序,除非提供了'ORDER BY'语句。而且oracle可以不处理主机变量数组吗?这正是我假设他正在使用的(所以不需要分裂,尽管其余的想法都是正确的)。 –

相关问题