옵티마이 저가 "select list pruning"을 적용하면 효과가 나타납니다. 이 경우 버그로 간주됩니다. 인라인 뷰에 집계 함수, 기본 쿼리의 참조되지 않은 열이 포함되어 있고 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
오류를 예상 없었다. 모든 것이 순조롭게 진행되었습니다. 이제 추적 파일 다음
_query_rewrite_vop_cleanup
매개 변수가
false
로 설정 할 수있는 해결 방법으로
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"
. 그러나 프로덕션 환경에서이 매개 변수를 설정해야하는 경우 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
);
결과 : 당신이 MOS에 액세스 할 수있는 경우
COL1
----------
1
6
2
4
5
3
7
,보고 1589317.1에서 16989676.8 걸릴 (버그 16989676이 - 12.1.0.2 릴리스에서 해결되어야한다), Bug 8945586 메모를.
내부 선택을 올바르게 실행하면 오류가 발생합니까? – xQbert
예. 별도로 실행하면 내부 쿼리 결과가 오류가 발생합니다. –
http://dba.stackexchange.com/questions/39674/why-is-a-non-single-group-group-function-allowed-in-a-subselect-but-not-on-it – Multisync