[英]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.