Oracle Query 문의 0 4 559

by yeszeus [SQL Query] [2019.04.16 16:06:21]


안녕하세요.

아래 테이블에서 최대값에 해당하는 값을 조회하려면 어떻게 해야 하나요.

name별, state별 최대값(gen_no) 및 해당 date 칼럼값 구하기.

 

[Table]

name  gen_no  start_date  state

==== =======  ========  =====

AAA     1           1.1 10:00    DONE

AAA     2           1.1 12:00    DONE

AAA     3            1.1 14:00   ACTIVE

AAA     4            1.1 15:00  ACTIVE

BBB     1           1.1 11:00   DONE

BBB     2           1.1 12:00   DONE

BBB     3           1.1 14:00   DONE

쿼리로 얻고자 하는 값은 아래와 같습니다.

-. 동일한 name별, state별 gen의 최대값에 해당하는 date Colume

name  state     gen_no               date

                     (name별max값)

===== ==== ================  =====

AAA    DONE           2              1.1 12:00

AAA   ACTIVE           4              1.1 15:00 

BBB   DONE           3              1.1 14:00

by 마농 [2019.04.16 16:50:24]
WITH t AS
(
SELECT 'AAA' name, 1 gen_no, '1.1 10:00' start_date, 'DONE' state FROM dual
UNION ALL SELECT 'AAA', 2, '1.1 12:00', 'DONE'   FROM dual
UNION ALL SELECT 'AAA', 3, '1.1 14:00', 'ACTIVE' FROM dual
UNION ALL SELECT 'AAA', 4, '1.1 15:00', 'ACTIVE' FROM dual
UNION ALL SELECT 'BBB', 1, '1.1 11:00', 'DONE'   FROM dual
UNION ALL SELECT 'BBB', 2, '1.1 12:00', 'DONE'   FROM dual
UNION ALL SELECT 'BBB', 3, '1.1 14:00', 'DONE'   FROM dual
)
SELECT *
  FROM (SELECT name, state, gen_no, start_date
             , ROW_NUMBER() OVER(PARTITION BY name, state ORDER BY gen_no DESC) rn
          FROM t
        ) a
 WHERE rn = 1
 ORDER BY name, gen_no
;

 


by 이준환 [2019.04.16 17:02:35]
/*
2019.04.16, Jun H. Lee
*/
WITH T(NAME, GEN_NO, START_DATE, STATE)
AS
(
    SELECT 'AAA', '1', '1.1 10:00', 'DONE' FROM DUAL UNION ALL
    SELECT 'AAA', '2', '1.1 12:00', 'DONE' FROM DUAL UNION ALL
    SELECT 'AAA', '3', '1.1 14:00', 'ACTIVE' FROM DUAL UNION ALL
    SELECT 'AAA', '4', '1.1 15:00', 'ACTIVE' FROM DUAL UNION ALL
    SELECT 'BBB', '1', '1.1 11:00', 'DONE' FROM DUAL UNION ALL
    SELECT 'BBB', '2', '1.1 12:00', 'DONE' FROM DUAL UNION ALL
    SELECT 'BBB', '3', '1.1 14:00', 'DONE' FROM DUAL
)
SELECT
  NAME
, STATE
, MAX(GEN_NO) AS MAX_GEN_NO
--------------------------------------------------------------------------------
-- MAX() 대신 MIN()도 같은 결과임, 숫자형 자료에서는 AVG()도 마찬가지임
, MAX(START_DATE)KEEP(DENSE_RANK FIRST ORDER BY GEN_NO DESC) AS START_DATE_OF_MAX_GEN_NO_1
, MAX(START_DATE)KEEP(DENSE_RANK LAST ORDER BY GEN_NO ASC) AS START_DATE_OF_MAX_GEN_NO_2
, MAX(START_DATE)KEEP(DENSE_RANK FIRST ORDER BY GEN_NO ASC) AS START_DATE_OF_MIN_GEN_NO_1
, MAX(START_DATE)KEEP(DENSE_RANK LAST ORDER BY GEN_NO DESC) AS START_DATE_OF_MIN_GEN_NO_2
--------------------------------------------------------------------------------
FROM T
GROUP BY NAME, STATE
;

그룹함수()KEEP(DENSE_RANK FIRST/LAST .. ORDER BY .. ASC/DESC)


이를 활용하시면 좀더 유연한 활용이 가능할 듯 싶습니다.

 


by yeszeus [2019.04.17 08:17:24]

name 값은 다양하게 추가되며 동일한 name값에서  gen_no는 1씩 증가됩니다.

이처럼 고정데이타가 아닌 추가되는경우에는 with밑에 select문을 어떻게 주어야하나요


by 마농 [2019.04.17 08:20:42]

WITH 문을 그대로 작성하라는 의미가 아닙니다.
WITH 문은 쿼리 테스트용으로 만든 것 뿐입니다.
SELECT 절만 참고하시면 됩니다.

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