您看到的是優化程序應用「選擇列表修剪」的效果。在這種情況下,它被認爲是一個錯誤 - 如果一個內嵌視圖包含聚合函數,主查詢中的未引用列,並且沒有group by
子句,優化器將決定簡單地刪除那些未引用的列( SLP - 選擇列表修剪):
環境:Windows x64;甲骨文12.1.0.1.0
-- test-table
create table t1 as
select level as col1
, level as col2
from dual
connect by level <= 7;
-- gather statistic on t1 table.
exec dbms_stats.gather_table_stats('', 'T1');
現在讓我們執行與啓用10053痕跡是越野車查詢和看到的掩護下,會發生什麼:
alter session set tracefile_identifier='no_group_by';
alter session set events '10053 trace name context forever';
select /*+ qb_name(outer) */ col1
from (
select /*+ qb_name(inner) */ max(col1) as col1
, col2
from t1
);
COL1
----------
7
alter session set events '10053 trace name context off';
有沒有預期ORA-00937
錯誤。一切順利。現在跟蹤文件:
OPTIMIZER INFORMATION
******************************************
----- Current SQL Statement for this session (sql_id=d14y7zuxvvfbw) -----
select /*+ qb_name(outer) */ col1
from (
select /*+ qb_name(inner)*/max(col1) as col1
, col2
from t1
)
*******************************************
.....
Query transformations (QT)
**************************
....
SVM: SVM bypassed: Single grp set fct (aggr) without group by.
/* That's where we lose our COL2 */
SLP: Removed select list item COL2 from query block INNER
query block OUTER (#0) unchanged
....
Final query after transformations:******* UNPARSED QUERY IS *******
SELECT /*+ QB_NAME ("OUTER") */ "from$_subquery$_001"."COL1" "COL1"
FROM (SELECT /*+ QB_NAME ("INNER") */ MAX("T1"."COL1") "COL1"
FROM "HR"."T1" "T1") "from$_subquery$_001"
變通方法是_query_rewrite_vop_cleanup
參數可以設置爲false
。但是,如果需要在生產環境中設置此參數,當然需要諮詢oracle支持。
alter session set "_query_rewrite_vop_cleanup"=false;
session altered
select /*+ qb_name(outer) */ col1
from (
select /*+ qb_name(inner) */ max(col1) as col1
, col2
from t1
);
結果:
Error report -
SQL Error: ORA-00937: not a single-group group function
00937. 00000 - "not a single-group group function"
當我們添加group by
子句,查詢工作正常。
select /*+ qb_name(outer) */ col1
from (
select /*+ qb_name(inner) */ max(col1) as col1
, col2
from t1
group by col2
);
結果:
COL1
----------
1
6
2
4
5
3
7
如果你有機會獲得MOS,看看1589317.1,16989676.8(錯誤16989676 - 應固定在12.1.0.2版本),Bug 8945586筆記。
但是,如果你只是運行內部選擇正確,你會得到一個錯誤? – xQbert 2014-12-05 18:55:19
是的。如果單獨運行,則內部查詢會導致錯誤。 – 2014-12-05 18:59:28
http://dba.stackexchange.com/questions/39674/why-is-a-non-single-group-group-function-allowed-in-a-subselect-but-not-on-it – Multisync 2014-12-05 19:18:56