簡體   English   中英

oracle sql 聯合訂購

[英]oracle sql union order by

這是一個認證題case A和case B,為什么在case B有效,而在case A無效

case A (not working)
select col_a, col_b, 'b' from table_a
union
select col_a, col_b, 'a' from table_a
order by 'b';

case B (working)
select col_a, col_b, 'b' from table_a order by 'b';

您正在按字符串文字'a'對數據進行排序,它與任何其他字符串文字一樣好,例如'Littlefoot' :兩者都無用,但被允許

SQL> select dname, 'a' from dept order by 'a';

DNAME          '
-------------- -
ACCOUNTING     a
RESEARCH       a
SALES          a
OPERATIONS     a

SQL> select dname, 'a' from dept order by 'Littlefoot';

DNAME          '
-------------- -
ACCOUNTING     a
RESEARCH       a
SALES          a
OPERATIONS     a

SQL>

order by子句 - 適用於union ed 查詢 - 適用於該 union 返回的整個數據集:

SQL> select dname, 'a' from dept where deptno <= 20
  2  union
  3  select dname, 'b' from dept where deptno > 20
  4  order by dname;

DNAME          '
-------------- -
ACCOUNTING     a
OPERATIONS     b
RESEARCH       a
SALES          b

SQL>

如您所知,在這種情況下按字符串文字排序將不起作用:

SQL> select dname, 'a' from dept where deptno <= 20
  2  union
  3  select dname, 'b' from dept where deptno > 20
  4  order by 'Littlefoot';
order by 'Littlefoot'
         *
ERROR at line 4:
ORA-01785: ORDER BY item must be the number of a SELECT-list expression


SQL>

該錯誤的字面意思是:

您試圖執行包含 ORDER BY 子句的 SELECT 語句,該子句引用了與 SELECT 列表中的有效列不對應的列號。

正如您已經被告知的那樣,您可以使用別名或列的position ,或者將該union用作子查詢,然后按字符串文字應用排序 - 在這種情況下,它將(再次)起作用:

SQL> select *
  2  from (select dname, 'a' from dept where deptno <= 20
  3        union
  4        select dname, 'b' from dept where deptno > 20
  5       )
  6  order by 'Littlefoot';

DNAME          '
-------------- -
ACCOUNTING     a
OPERATIONS     b
RESEARCH       a
SALES          b

SQL>

那是沒用的(就像以前一樣),但它是允許的。

人們可能希望這樣的事情會起作用(“希望”通過隱式數據轉換,其中 Oracle 會將'2' (字符串)轉換為2 (數字)並按位置排序),但是 - 不:

SQL> select dname, 'a' from dept where deptno <= 20
  2  union
  3  select dname, 'b' from dept where deptno > 20
  4  order by '2';
order by '2'
         *
ERROR at line 4:
ORA-01785: ORDER BY item must be the number of a SELECT-list expression

當然,位置排序有效:

SQL> select dname, 'a' from dept where deptno <= 20
  2  union
  3  select dname, 'b' from dept where deptno > 20
  4  order by 2;

DNAME          '
-------------- -
RESEARCH       a
ACCOUNTING     a
SALES          b
OPERATIONS     b

SQL>

所以,我懷疑union出了問題 也許這是關於UNION返回DISTINCT數據集的事實,並且 - 有了它 - ORDER BY子句不能引用不屬於SELECT列列表的列,從字面上看。

'b'是字符串文字而不是列的標識符(因為列的標識符是帶引號的標識符"'B'" )。

您可以使用列號:

select col_a, col_b, 'b' from table_a union
select col_a, col_b, 'a' from table_a
order by 3;

或使用帶引號的標識符並將文字轉換為大寫:

select col_a, col_b, 'b' from table_a union
select col_a, col_b, 'a' from table_a
order by "'B'";

或者給該列一個別名並使用它:

select col_a, col_b, 'b' AS b from table_a union
select col_a, col_b, 'a' from table_a
order by b;

請參閱SELECT文檔

集合運算符:UNION、UNION ALL、INTERSECT、MINUS

[...]

order_by_clause

使用ORDER BY子句對語句返回的行進行排序。 如果沒有order_by_clause ,則無法保證多次執行的同一查詢將以相同的順序檢索行。

[...]

表達式

expr根據expr的值對行進行排序。 該表達式基於 select 列表中的列或FROM子句中的表、視圖或實例化視圖中的列。

[...]

ORDER BY子句的限制

以下限制適用於ORDER BY子句:

  • 如果您在此語句中指定了DISTINCT運算符,則此子句不能引用列,除非它們出現在 select 列表中。

您正在使用隱式應用DISTINCT運算符的UNION (而不是UNION ALL ),因此限制適用於您“引用列,除非它們出現在 select 列表中。” select 列表中列的標識符是帶引號的標識符"'B'"而不是字符串文字'b' (也不是字符串文字'B' ),您需要這樣引用它(或通過select 列表中的 position 或別名)。

注意:即使不應用隱式DISTINCT的附加限制, UNION查詢的基本限制是“表達式基於 select 列表中的列或FROM子句中的表、視圖或物化視圖中的列”和文字'b'不是 select 列表中的列,也不是FROM子句的 object 中的列,因此如果您使用UNION ALL而不是UNION ,它將是有效的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM