2

我有一个带有主键 MY_PK 的表 MY_TABLE。然后,我有一个有序主键列表,例如 (17,13,35,2,9)。

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

我最初做的是:

SELECT * FROM MY_TABLE WHERE MY_PK IN (:my_list)

但是返回行的顺序是随机的,不再与给定键的顺序相对应。有没有办法做到这一点?我唯一想到的是制作许多 SELECT 语句并将它们与 UNION 连接,但是我的主键列表可能很长,并且包含数百甚至数千个键。我想到的替代方法是在应用程序中重新排序行,但我更喜欢不需要这样做的解决方案。

4

3 回答 3

2

Oracle 仅在使用显式 ORDER BY 语句排序时才保证结果集的顺序。所以你的实际问题是,“我如何保证将我的结果排序为任意顺序?”

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

我假设您将 ID 列表作为字符串获取。(如果你将它们作为一个数组或类似的类似表格的东西,生活会更容易。)所以首先你需要标记你的字符串。在我的示例中,我使用了另一个 SO 线程splitter中的函数。我将在公共表表达式中使用它来获取一些行,并使用 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

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

于 2012-09-21T14:49:42.973 回答
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
于 2012-09-21T14:28:15.293 回答
1

保证结果集顺序的方法是使用 ORDER BY,所以我要做的是在一个临时表中插入 2 列您的主键和一个稍后用于创建 ORDER BY 的 secuencial ID。您的临时表将是:

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

之后,只需使用您的表和 PrimaryKey 列上的临时表的连接,并按临时表的 ID 列排序。

于 2012-09-21T21:56:09.117 回答