假設我想動態定義一些表格資料以在查詢中使用,而無需創建物理表:
------------ ------------
|COLUMN_VALUE|COLUMN_VALUE|
------------ ------------
|1 |a |
|2 |b |
|5 |e |
|4 |d |
|3 |c |
------------ ------------
(注意順序)
我怎樣才能盡可能簡潔地做到這一點?
我能想到的(不太漂亮):
with
x as (
select
column_value
from
table (sys.odcinumberlist(1, 2, 5, 4, 3))),
y as (
select
column_value
from
table (sys.odcivarchar2list('a', 'b', 'e', 'd', 'c')))
select
x.column_value,
y.column_value
from
x
inner join y on x.rownum = y.rownum;
但是這不起作用,因為它出錯了ORA-01747: invalid user.table.column, table.column, or column specification。顯然,rownum使用內置table()函式時不支持偽列。
row_number() over (order by column_value asc)在 CTE 中使用似乎有用,但會強制對列值進行排序。這是不可取的,因為值應該按照它們在表函式中定義的順序出現。
uj5u.com熱心網友回復:
Oracle Database Ideas 論壇上有一個社區建議向標量集合添加一個ordinality偽列,但我認為它不太可能在我們的有生之年實作。還有一個語法建議允許使用values類似于Postgres Values lists的子句動態宣告集合,盡管我現在找不到它。
目前您的選擇是:
使用多個
select from dual查詢union all來明確定義所有必需的行。定義自定義物件和集合型別以使用
table()物件宣告性語法。
我同意兩者都不理想。
關于生成的行編號,您可以使用
row_number() over(order by null)
從技術上講,這不能保證保留順序,但從 Oracle 21c 開始,它似乎在實踐中這樣做了。
select column_value
, row_number() over (order by null) as rn
from table (sys.odcivarchar2list('a', 'b', 'e', 'd', 'c'));
COLUMN_VALUE RN
------------ ----------
a 1
b 2
e 3
d 4
c 5
關于您的 ORA-01747 錯誤x.rownum,這不是因為table()操作員周圍的任何限制。這樣的結構有兩個問題(查詢的簡化版本):
with demo as
( select dummy from dual )
select x.rownum from demo x
- CTE
demo沒有名為“rownum”的列。它只有一列 (dummy),因此這是您可以參考的唯一 x.column。 - 即使您添加
rownum到查詢中,也不能像列一樣參考它,x.rownum因為它是關鍵字。解決方案是在 CTE 中將其別名為“seq”或“rn”,然后可以參考:
with demo as
( select dummy, rownum as rn from dual )
select x.rn from demo x
uj5u.com熱心網友回復:
解決方案是為 rownum 列添加別名(也整理了查詢):
select
x.column_value,
y.column_value
from
(select column_value, rownum as rn from table (sys.odcinumberlist(1, 2, 5, 4, 3))) x
inner join
(select column_value, rownum as rn from table (sys.odcivarchar2list('a', 'b', 'e', 'd', 'c'))) y on x.rn = y.rn;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/400987.html
標籤:sql 甲骨文 甲骨文12c 甲骨文19c oracle21c
下一篇:如何獲得合計占總數的百分比
