결과 컬럼이 1개 이며, 1행을 보여주고자 합니다. group by, rownum 어느것이 좋나요? 1 11 2,249

by 물개 [Oracle 기초] [2013.12.06 16:52:58]


decode( 서브쿼리, 'null', 'N', 'Y') 이런 형태에서

서브쿼리에서 결과값이 2개 이상이면 에러가 나타나는 현상을 알게 되었습니다.

group by 를 쓴 경우와 rownum = 1 이란 경우로

결과값을 가져올 수 있는 것 같습니다..

실행계획을 보니 약간의 차이만 보입니다.



실제로 어느 것이 더 좋고 실무에서 더 많이 쓰이는 지 알고 싶습니다.

선배님의 의견을 듣고 싶습니다.


=======================================================
이하는 group by 구문 과 rownum 적용한 예문 입니다 .10g에서 테스트해보았습니다.

with t as(
   select '1234' userid, '20130101' fromdd, '20131231' todd, 'Y' useyn from dual
   union all select '1234' , '20130101' , '20131231', 'Y' from dual
   union all select '1234' , '20130101' , '20131231', 'Y' from dual
   union all select '1234' , '20130101' , '20131231', 'Y' from dual
   union all select '1234' , '20130101' , '20131231', 'Y' from dual
   union all select '1234' , '20130101' , '20131231', 'Y' from dual
   union all select '1234' , '20130101' , '20131231', 'Y' from dual
   union all select '1234' , '20130101' , '20131231', 'Y' from dual
   )
   select userid  
   from t
   where userid = '1234'
   AND TO_CHAR (SYSDATE, 'YYYYMMDD') BETWEEN fromdd AND todd
   AND useyn = 'Y'   group by userid;


with t as(
   select '1234' userid, '20130101' fromdd, '20131231' todd, 'Y' useyn from dual
   union all select '1234' , '20130101' , '20131231', 'Y' from dual
   union all select '1234' , '20130101' , '20131231', 'Y' from dual
   union all select '1234' , '20130101' , '20131231', 'Y' from dual
   union all select '1234' , '20130101' , '20131231', 'Y' from dual
   union all select '1234' , '20130101' , '20131231', 'Y' from dual
   union all select '1234' , '20130101' , '20131231', 'Y' from dual
   union all select '1234' , '20130101' , '20131231', 'Y' from dual
   )
   select userid  
   from t
   where userid = '1234'
   AND TO_CHAR (SYSDATE, 'YYYYMMDD') BETWEEN fromdd AND todd
   AND useyn = 'Y'
   and rownum = 1;
 
by 우리집아찌 [2013.12.06 17:00:10]
 
-- 전 그냥 MAX나 MIN을 더 많이 씁니다.
with t as(
 select '1234' userid, '20130101' fromdd, '20131231' todd, 'Y' useyn from dual
 union all select '1234' , '20130101' , '20131231', 'Y' from dual
 union all select '1234' , '20130101' , '20131231', 'Y' from dual
 union all select '1234' , '20130101' , '20131231', 'Y' from dual
 union all select '1234' , '20130101' , '20131231', 'Y' from dual
 union all select '1234' , '20130101' , '20131231', 'Y' from dual
 union all select '1234' , '20130101' , '20131231', 'Y' from dual
 union all select '1234' , '20130101' , '20131231', 'Y' from dual
 )
 
 select MAX(userid) , MIN(userid)
 from t
 where userid = '1234'
 AND TO_CHAR (SYSDATE, 'YYYYMMDD') BETWEEN fromdd AND todd
 AND useyn = 'Y'

by 물개 [2013.12.06 17:07:29]
답변감사합니다.
MAX MIN 방법도 있었군요!
쿼리의 튜닝이나 정확성? 측면에서는 어느 방법이든 상관없을까요?

by 우리집아찌 [2013.12.06 17:39:21]
   -- 또다른 방법으론 DISTINCT 도 있군요..
   select distinct userid 
   from t
   where userid = '1234'
   AND TO_CHAR (SYSDATE, 'YYYYMMDD') BETWEEN fromdd AND todd
   AND useyn = 'Y'  ;

by 우리집아찌 [2013.12.06 17:43:34]

전 그냥 쿼리라인이 짧아져서 ..


by 물개 [2013.12.07 13:01:44]
distinct 방법도 있군요!

정말 많은 도움이 되었습니다.

감사합니다!

by 마농 [2013.12.06 17:07:47]
데이터의 존재여부만 체크하는 경우엔
다 읽고난 후 추려내는 것보다는 1건만 읽고 멈추도록 하는것이 좋습니다.

by 물개 [2013.12.06 17:31:36]
답변 감사합니다.

용도에 맞게 사용하는 것이 중요하다는 의미로 받아드리겠습니다.

또한, 성능상에도.. 좋다는 것으로..

by 빈이 [2013.12.06 17:14:34]

MIN, MAX 보다는 ROWNUM 이 낫지 않나요?

조건절의 값을 MIN, MAX 해도 동일한 데이터가 여러ROW일 뿐이지만..

ROWNUM은 조회 값이 1개라도 찾으면 결과 나올 거 같고

MIN, MAX는 비교를 할거 같은.....;;

고수님들의 답변을 ;;;

음..? 마농님이.. 답변 다셨네;;

by 물개 [2013.12.06 17:33:31]
답변 감사드립니다.

MIN MAX도 성능상에서 group by보다? 좋게 나와서 놀랐습니다만...

rownum가 좋은 방법 같다는 생각으로 기웁니다.

by 마농 [2013.12.06 17:53:00]
-- 조건컬럼(userid)에 반드시 인덱스가 있어야 하구요.
-- 인덱스가 있을 경우 MIN(userid) 하면 실행계획이 first row 로 나옵니다.
-- Rownum 과 유사하게 동작한다고 보시면 되구요.
-- 어차피 userid 를 조건으로 주기 때문에 GROUP BY userid 는 무의미하다고 보이네요.
-- 저는 이런식으로 사용합니다.
SELECT m.*
     , (SELECT NVL(MIN('Y'), 'N')
          FROM sub s
         WHERE s.useyn = 'Y'
           AND TO_CHAR(sysdate, 'yyyymmdd') BETWEEN s.fromdd AND s.todd
           AND s.userid = m.userid
           AND ROWNUM <= 1
        ) yn
  FROM main m
;

by 물개 [2013.12.07 13:06:27]
정성스런 답변 감사드립니다.

main 과 sub의 userid 비교에 놀랐습니다./

날짜 구간에서 sub 약칭 사용도 좋은 방법 같습니다.

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