오라클 버전별 group by쿼리의 정상실행/쿼리오류 0 4 6,552

by poodle [PL/SQL] group by version [2017.03.17 17:58:57]


안녕하세요~  이전질문에 이어 또 다시 문의 드려요

이전질문 : http://www.gurubee.net/article/69198

Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi->

Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

 

현재 10g에서 조회가 잘되던 쿼리인데 11g에선  group by 에서 오류가 나요

ora-00979 : group by 표현식이 아닙니다.

group by에 bud_nm, mok_nm, biz_nm이 없어서 오류가 난거였어요

 

이상한건 왜! 도대체 왜 쿼리가 10g에선 실행이 되고 11g에선 안되는지

이게 서버 버전때문인건지?? 세팅 때문인지??? 버전 때문이라면 새로운 버전에서 더 오류없이 잘 돌아야 되는게 아닌지 -_-;;;;

너무너무 궁금합니다.

대답 꼭 부탁드려요

 

아래의 쿼리는 10g에서 오류없이 실행되고 11g에서 오류가 나는 쿼리입니다.

 SELECT
        S.BUD_NM,
        S.MOK_NM,
        S.BIZ_NM,
        SUM(S.CDA_AMT) CDA_AMT,
        S.BUD_YY                   
    FROM
        ( SELECT
            M.BUD_YY,
            M.UNT_ACC,
            M.UNT_BUD,
            SF_CODENM('BUD',BUD_CD) BUD_NM,
            SF_CODENM('BIZ',BIZ_CD) BIZ_NM,
            SF_CODENM('MOK',MOK_CD) MOK_NM,
            M.BUD_CD,
            M.BIZ_CD,
            M.MOK_CD,
           '1' CDA_AMT
        FROM
            TABLE M                                       
        WHERE                                                      
             M.BUD_YY =  '2016'
                    ) S      
    WHERE
        1=1                      
    GROUP BY
        S.BUD_YY,
        S.UNT_ACC,
        S.UNT_BUD,
        S.BUD_CD,
        S.MOK_CD,
        S.BIZ_CD

질문용으로 쿼리를 위와 같은 형식으로 작성을 해보았는데 아래 쿼리는 오류가 나네요.

위의 쿼리와 별로 다를게 없는 쿼리 인듯 보이는데요....

 

with  table1 as
(
select '1' 교실코드, '호랑이' 이름, '1' 국어코드, '100' 국어점수 , '2' 영어코드, '100' 영어점수 from dual union all          
select '1', '고양이', '1', '100', '2', '100' from dual union all
select '2', '강아지', '1', '100', '2', '100' from dual
)
,table2 as
(
select '1' 교실코드 ,'개나리반' 교실명 from dual union all
select '2','진달래반' from dual
)
select sum(c.국어점수), c.교실코드  from    
    (select a.*, b.교실명 from table1 a, table2 b where a.교실코드 = b.교실코드) c
group by c.교실명    ;
 

     

 

 

by jkson [2017.03.17 18:18:13]

서버 버전에 따른 차이인 것 같네요.(10g 11g 차이가 아니라 11g에서도 버전마다 다른듯..)

제 생각입니다만..
10g에서는 S.BUD_NM, S.MOK_NM, S.BIZ_NM 컬럼들이 SF_CODENM function을 통해 나오는 컬럼들이므로 BIZ_CD, MOK_CD에 종속적인 컬럼이다라고 정의하는 것 같습니다.
그런데 실제로 function에서는 같은 입력에 대해 다른 값을 출력할 수도 있으니 따지고 보면 종속적인 값은 아니죠.
그런이유로 fix가 된 게 아닌가 하는데

=> 취소. deterministic function을 지정하고 해도 오류나기도 하고 여러 케이스 테스트 해보니 이런 이유는 아닌듯..

실제로 아래를 테스트 해보시면

select dt, dt2
from
(
select sysdate dt, to_char(sysdate,'yyyymmdd') dt2
from dual
)
group by dt 

오류가 납니다. 그런데..

alter session set optimizer_features_enable = '11.1.0.7'

해주신 후 해보세요. 오류가 안 날 겁니다.

결론적으로는 오라클에서 group by에 대한 내부 로직을 바꾸었고

'group by 를 사용할 때 select절에 오는 집계함수를 제외한 모든 컬럼은 group by 절에 정의되어야 한다'

로 최종 결정을 한 것 같네요.


by 마농 [2017.03.17 21:42:47]

구문으로만 보면 에러나는게 당연한 거구요.
10G 에서 에러 안난게 오히려 이상한 거죠.
에러 안난 이유를 추측해 보면 쿼리변환을 의심해 볼 수 있습니다.
인라인뷰를 사용했지만 쿼리 변환에 의해서
인라인뷰가 뷰머징 된 상태로 실행될 것이구요.
이 경우 cd 로만 Group By 해도 정상 수행됩니다.
nm 은 어차피 cd 에 종속되는 값이니까요.
테스트로 인라인뷰를 제거하고 한번에 그룹바이를 수행해 보세요.
cd 로만 그룹바이 해도 cd 를 인자로 하는 함수가 정상 수행될 것입니다.


아래 테스트 쿼리는 Group By CD 를 해야 그나마 비슷한 쿼리가 되죠.
Group By NM 하셨으니 다른 쿼리로 봐야 합니다.
그리고 Group By cd 를 했더라도 비슷한 쿼리가 되려면
조인 형태가 아닌 스칼라서브쿼리 형태로 nm 을 가져오게 해야 하겠죠.


by jkson [2017.03.17 22:31:33]

아 그렇네요. 마농님 댓글 읽고나니 group by 정책의 변화라기보다 쿼리변환 로직이 바뀌었다고 보는 게 맞겠네요.


by poodle [2017.03.22 18:10:15]

답변 감사드려요~

마농님 말씀대로  힌트를 NO_MERGE로 주니 'group by 표현식이 아닙니다' 라고 오류가 나오네요
항상 답변 감사드려요~

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입