我在Oracle中创建了一个类型表来保存多个值。
TYPE NUM_ARRAY IS TABLE OF NUMBER
在查询中使用此类型时,我希望我的查询按顺序返回,具体取决于此类型的排列方式。像这样:
SELECT *
FROM
TABLE(NUMBER_ARRAY(4,3,2,1)) t1
LEFT OUTER JOIN
TABLE(NUMBER_ARRAY(3)) t2
ON t1.column_value=t2.column_value;
结果
column_value column_value_1
3 3
4
1
2
我希望这会返回结果,以便从表t1
中保留排序,但是如果我没有放ORDERED BY
它似乎是通过自然排序来完成的,如果我做一些像ORDERED BY t1.column_value
这样的事情也可以通过自然顺序来做。
在SQL / PL SQL中是否有更好的方法让它按类型表中的顺序对返回的元素进行排序?
答案 0 :(得分:2)
您可以为两个表中的每一行分配一个伪行号,并按顺序排序,但您必须使用内联视图:
SELECT t1.column_value, t2.column_value
FROM
(
SELECT column_value, ROW_NUMBER() OVER (ORDER BY null) AS rn
FROM TABLE(NUMBER_ARRAY(4,3,2,1))
) t1
LEFT OUTER JOIN
(
SELECT column_value, ROW_NUMBER() OVER (ORDER BY null) AS rn
FROM TABLE(NUMBER_ARRAY(3))
) t2
ON t1.column_value=t2.column_value
ORDER BY t1.rn, t2.rn;
COLUMN_VALUE COLUMN_VALUE
------------ ------------
4
3 3
2
1
但是一个嵌套的表,即使是你这样构建的表,也没有固有的顺序。看起来它确实和行为一样(至少就我所见,有趣),但并不能保证一直这样做;所以你有一天会得到意想不到的结果。只订购了varrays。所以你可以这样声明你的类型:
create or replace TYPE NUMBER_ARRAY IS VARRAY(10) OF NUMBER;
/
...并且相同的查询给出相同的结果。但是你会受到你给它的大小的限制,所以你真的需要知道你期望有多少元素(并设置它非常高以涵盖所有可能性会产生内存成本)。 / p>
PL / SQL documentation for varrays says“当您从数据库中存储和检索varray时,其索引和元素顺序保持稳定”。但是for nested tables it says“当您从数据库中存储和检索嵌套表时,嵌套表的索引和行顺序可能不会保持稳定”。
你真的没有在这里存储和检索,但似乎没有任何东西似乎表明订单总是稳定的,即使它的内存 - 它似乎就是这样,而且正如我所说它似乎永远是;但我不想依赖它。
同样在存储环境中,Tom Kyte said:
除非您有需要订购的东西,否则不要指望订购任何东西。
如果你不试图把它们变成“列” - 只要把它们放在数组中就行了 - 将保持顺序(对于varrays,而不是嵌套表)。 simple select * from table将按照它们进入的顺序返回数组。
“不嵌套的表”部分会让我避免依赖于那种明显的排序,尽管这也是关于从表中存储和检索的内容。