아래 상품변경이력에서 최근 1년 내에 ‘ZE367’ 상품의 변경구분코드가 ‘C2’인 최종 변경일시를 찾는 가장 효과적인 SQL을 고르시오.(단, ERD의 컬럼 나열 순서와 동일하게 PK 인덱스를 생성하였으며, 다른 인덱스는 없는 상태다)

상품변경이력_PK : [상품코드, 변경일시, 변경구분코드]

1번.
SELECT MAX(변경일시)
  FROM 상품변경이력
 WHERE 상품코드 = 'ZE367'
   AND 변경구분코드 = 'C2'
   AND 변경일시 = (SELECT MAX(변경일시)
						        FROM 상품변경이력
						       WHERE 상품번호 = 'ZE367'
						         AND 변경일시 >= TRUNC(ADD_MONTHS(SYSDATE, -12)));
2번.
SELECT MAX(변경일시)
  FROM 상품변경이력
 WHERE 상품코드 = 'ZE367'
   AND 변경구분코드 = 'C2'
   AND 변경일시 = (SELECT MAX(변경일시)
						        FROM 상품변경이력
						       WHERE 상품번호 = 'ZE367'
						         AND 변경일시 >= TRUNC(ADD_MONTHS(SYSDATE, -12))
						         AND 변경구분코드 = 'C2');
3번.
SELECT MAX(변경일시)
  FROM 상품변경이력
 WHERE 상품코드 = 'ZE367'
   AND 변경일시 >= TRUNC(ADD_MONTHS(SYSDATE, -12))
   AND 변경구분코드 = 'C2';
4번.
SELECT /*+ INDEX_DESC(H) */
		   변경일시
  FROM 상품변경이력 H
 WHERE 상품코드 = 'ZE367'
   AND 변경일시 >= TRUNC(ADD_MONTHS(SYSDATE, -12))
   AND 변경구분코드 = 'C2'
   AND ROWNUM <= 1;

Edited by 김문석

Untitled

--AS-IS 쿼리
SELECT X.카드번호
  FROM (SELECT C.카드번호, ROWNUM RNUM
          FROM 주문 A
             , 주문이력 B
             , 결제이력 C
         WHERE A.회원번호 = 'C13991'
           AND A.주문상태코드 ='12'
           AND B.주문번호 = A.주문번호
           AND C.주문이력번호 = B.주문이력번호
         ORDER BY C.결제일자 DESC
  ) X
 WHERE RNUM = 1;

/*
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name         | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |              |      1 |        |      1 |00:00:00.01 |      87 |
|*  1 |  VIEW                             |              |      1 |      8 |      1 |00:00:00.01 |      87 |
|   2 |   SORT ORDER BY                   |              |      1 |      8 |     20 |00:00:00.01 |      87 |
|   3 |    COUNT                          |              |      1 |        |     20 |00:00:00.01 |      87 |
|   4 |     NESTED LOOPS                  |              |      1 |        |     20 |00:00:00.01 |      87 |
|   5 |      NESTED LOOPS                 |              |      1 |      8 |     20 |00:00:00.01 |      67 |
|   6 |       NESTED LOOPS                |              |      1 |      4 |     10 |00:00:00.01 |      44 |
|*  7 |        TABLE ACCESS BY INDEX ROWID| 주문         |      1 |      2 |      5 |00:00:00.01 |      22 |
|*  8 |         INDEX RANGE SCAN          | IX01_주문    |      1 |     20 |     19 |00:00:00.01 |       3 |
|   9 |        TABLE ACCESS BY INDEX ROWID| 주문이력     |      5 |      2 |     10 |00:00:00.01 |      22 |
|* 10 |         INDEX RANGE SCAN          | IX01_주문이력|      5 |      2 |     10 |00:00:00.01 |      12 |
|* 11 |       INDEX RANGE SCAN            | IX01_결제이력|     10 |      2 |     20 |00:00:00.01 |      23 |
|  12 |      TABLE ACCESS BY INDEX ROWID  | 결제이력     |     20 |      2 |     20 |00:00:00.01 |      20 |
------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - filter("RNUM"=1)
   7 - filter("A"."주문상태코드"='12')
   8 - access("A"."회원번호"='C13991')
  10 - access("B"."주문번호"="A"."주문번호")
  11 - access("C"."주문이력번호"="B"."주문이력번호")
 
*/

<aside> ❓ 문제

주문데이터 입력 시 최종 결제 카드번호 찾는 쿼리 입니다. 해당 쿼리를 튜닝하세요.

<aside> 💡 정답