최소값을 구하려고하는데 ora-00904 오류가 나네요 0 4 1,716

by 리뉴사 [2016.03.08 16:35:15]


select sa.sp_location_fb
       , sp.sp_content
       , min(sp.sp_priority) over (partition by sa.sp_location_fb) as min_prior
       , sp.sp_priority
from selling_point sp, sp_apply sa 
where sp.sp_code = sa.sp_code
and sa.pro_code = '2016030700001'
and sp.sp_priority = min_prior

 

 

분명히 min(sp.sp_priority) over (partition by sa.sp_location_fb) as min_prior 여기서 as min_prior 해줫는데

and sp.sp_priority = min_prior  마지막줄에서 에러가 나네요 왜그런거죠...

 

by 겸댕2후니 [2016.03.08 16:42:08]

select절의 실행순서는 아래와 같습니다.

위의 쿼리는 where절을 수행할 시, select절의 알리아스를 사용했으므로 오류가 날수밖에 없습니다.

왜? where절 수행시에는 select절을 읽기 전이기 때문

1. from

2. where

3. group by

4. having

5. select

6. order by

 select * 
 from (
 select sa.sp_location_fb
        , sp.sp_content
        , min(sp.sp_priority) over (partition by sa.sp_location_fb) as min_prior
        , sp.sp_priority
 from selling_point sp, sp_apply sa 
 where sp.sp_code = sa.sp_code
 and sa.pro_code = '2016030700001')
 where sp.sp_priority = min_prior

 


by 리뉴사 [2016.03.08 16:43:58]

답변감사합니다


by 마농 [2016.03.08 16:49:03]

Alias 를 바로 인식할 수는 없습니다.
인라인뷰로 묶은 뒤 다음 단계에서 인식 가능합니다.
 

SELECT *
  FROM (SELECT sa.sp_location_fb
             , sp.sp_content
             , sp.sp_priority
             , MIN(sp.sp_priority) OVER(PARTITION BY sa.sp_location_fb) min_prior
          FROM selling_point sp
             , sp_apply      sa
         WHERE sp.sp_code  = sa.sp_code
           AND sa.pro_code = '2016030700001'
        )
 WHERE sp_priority = min_prior
;

그런데 위 방식은 비효율이 존재합니다.
TOP n 쿼리 방식으로 개선 가능합니다.
MIN 보다는 순위함수인 Rank 함수를 사용하는게 좋습니다.
 

SELECT *
  FROM (SELECT sa.sp_location_fb
             , sp.sp_content
             , sp.sp_priority
             , RANK() OVER(PARTITION BY sa.sp_location_fb ORDER BY sp.sp_priority) rk
          FROM selling_point sp
             , sp_apply      sa
         WHERE sp.sp_code  = sa.sp_code
           AND sa.pro_code = '2016030700001'
        )
 WHERE rk = 1
;

만약 sp_location_fb 별 sp_priority 값이 중복되지 않는다면?
RANK 대신 ROW_NUMBER 을 사용해도 되며
이 경우 GROUP BY KEEP 을 이용하는 방법도 가능합니다.
 

SELECT sa.sp_location_fb
     , MIN(sp.sp_content) KEEP(DENSE_RANK FIRST ORDER BY sp.sp_priority) sp_content
     , MIN(sp.sp_priority) sp_priority
  FROM selling_point sp
     , sp_apply      sa
 WHERE sp.sp_code  = sa.sp_code
   AND sa.pro_code = '2016030700001'
 GROUP BY sa.sp_location_fb
;

 


by 리뉴사 [2016.03.15 09:52:38]

친절한 답변 감사합니다^^

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