4.1.5 WHERE절 단독서브쿼리

  1. MAX - 마지막 한 건 조회하기

서브쿼리 결과를 1건만 만들어낸다(MAX이용)

-- 마지막 주문 한 건을 조회하는 SQL, ORD_SEQ가 가장 큰 데이터가 마지막 주문이다.
-- T_ORD 테이블을 두 번 읽기 떄문에 비효율적이다.
SELECT  *
FROM    T_ORD T1
WHERE   T1.ORD_SEQ = (SELECT MAX(A.ORD_SEQ) FROM T_ORD A);

20231218_141023.png

  1. MAX - 마지막 한 건 조회하기 (개선)
-- 마지막 주문 한 건을 조회하는 SQL, ORDER BY와 ROWNUM을 사용
SELECT  *
FROM    (
		SELECT  *
		FROM    T_ORD T1
		ORDER BY T1.ORD_SEQ DESC
		) A
WHERE  ROWNUM <= 1;

20231218_141100.png

  1. MAX - 마지막 주문일자의 주문조회하기
-- 마지막 주문 일자의 데이터를 가져오는 SQL
-- 필요시 ORD_DT 컬럼으로 구성된 인덱스를 만들어야한다.
SELECT  *
FROM    T_ORD T1
WHERE   T1.ORD_DT = (SELECT MAX(A.ORD_DT) FROM T_ORD A);

20231218_143720.png

  1. IN : 서브쿼리결과를 IN조건으로 받을 수 있다
-- 3월 주문 건수가 4건 이상인 고객의 3월달 주문 리스트

SELECT  *
FROM    T_ORD T1
WHERE   T1.ORD_DT >= TO_DATE('20170301','YYYYMMDD')
AND     T1.ORD_DT < TO_DATE('20170401','YYYYMMDD')
AND     T1.CUS_ID IN (
			SELECT  A.CUS_ID
			FROM    T_ORD A
			WHERE   A.ORD_DT >= TO_DATE('20170301','YYYYMMDD')
			AND     A.ORD_DT < TO_DATE('20170401','YYYYMMDD')
			GROUP BY A.CUS_ID
			HAVING COUNT(*)>=4
);

| ORD_SEQ | CUS_ID   | ORD_DT                  | ORD_ST | PAY_DT                  | PAY_TP | ORD_AMT | PAY_AMT |
| ------- | -------- | ----------------------- | ------ | ----------------------- | ------ | ------- | ------- |
| 442     | CUS_0010 | 2017-03-01 00:00:00.000 | COMP   | 2017-03-01 00:00:00.000 | CARD   | 700     | 700     |
| 443     | CUS_0020 | 2017-03-01 00:00:00.000 | COMP   | 2017-03-01 00:00:00.000 | BANK   | 2,830   | 2,830   |
| 444     | CUS_0030 | 2017-03-01 00:00:00.000 | COMP   | 2017-03-01 00:00:00.000 | BANK   | 630     | 630     |
| 445     | CUS_0040 | 2017-03-01 00:00:00.000 | COMP   | 2017-03-01 00:00:00.000 | BANK   | 3,700   | 3,700   |
| 446     | CUS_0050 | 2017-03-01 00:00:00.000 | COMP   | 2017-03-01 00:00:00.000 | CARD   | 1,100   | 1,100   |
| 502     | CUS_0010 | 2017-03-11 00:00:00.000 | COMP   | 2017-03-11 00:00:00.000 | CARD   | 800     | 800     |
| 503     | CUS_0020 | 2017-03-11 00:00:00.000 | COMP   | 2017-03-11 00:00:00.000 | BANK   | 3,420   | 3,420   |
| 504     | CUS_0030 | 2017-03-11 00:00:00.000 | COMP   | 2017-03-11 00:00:00.000 | BANK   | 1,000   | 1,000   |
| 505     | CUS_0040 | 2017-03-11 00:00:00.000 | COMP   | 2017-03-11 00:00:00.000 | BANK   | 3,600   | 3,600   |
| 506     | CUS_0050 | 2017-03-11 00:00:00.000 | COMP   | 2017-03-11 00:00:00.000 | CARD   | 1,200   | 1,200   |
| 562     | CUS_0010 | 2017-03-21 00:00:00.000 | COMP   | 2017-03-21 00:00:00.000 | CARD   | 2,800   | 2,800   |
| 563     | CUS_0020 | 2017-03-21 00:00:00.000 | COMP   | 2017-03-21 00:00:00.000 | BANK   | 3,600   | 3,600   |
| 564     | CUS_0030 | 2017-03-21 00:00:00.000 | COMP   | 2017-03-21 00:00:00.000 | BANK   | 3,000   | 3,000   |
| 565     | CUS_0040 | 2017-03-21 00:00:00.000 | COMP   | 2017-03-21 00:00:00.000 | BANK   | 600     | 600     |
| 566     | CUS_0050 | 2017-03-21 00:00:00.000 | COMP   | 2017-03-21 00:00:00.000 | CARD   | 200     | 200     |
| 622     | CUS_0010 | 2017-03-31 00:00:00.000 | COMP   | 2017-03-31 00:00:00.000 | CARD   | 2,900   | 2,900   |
| 623     | CUS_0020 | 2017-03-31 00:00:00.000 | COMP   | 2017-03-31 00:00:00.000 | BANK   | 3,500   | 3,500   |
| 624     | CUS_0030 | 2017-03-31 00:00:00.000 | COMP   | 2017-03-31 00:00:00.000 | BANK   | 3,100   | 3,100   |
| 625     | CUS_0040 | 2017-03-31 00:00:00.000 | COMP   | 2017-03-31 00:00:00.000 | BANK   | 3,500   | 3,500   |
| 626     | CUS_0050 | 2017-03-31 00:00:00.000 | COMP   | 2017-03-31 00:00:00.000 | CARD   | 3,300   | 3,300   |

-- 서브쿼리
SELECT  A.CUS_ID
			FROM    T_ORD A
			WHERE   A.ORD_DT >= TO_DATE('20170301','YYYYMMDD')
			AND     A.ORD_DT < TO_DATE('20170401','YYYYMMDD')
			GROUP BY A.CUS_ID
			HAVING COUNT(*)>=4
| CUS_ID   |
| -------- |
| CUS_0010 |
| CUS_0040 |
| CUS_0050 |
| CUS_0020 |
| CUS_0030 |

-- 맨 위 쿼리는 아래와 동치다
SELECT  *
FROM    T_ORD T1
WHERE   T1.ORD_DT >= TO_DATE('20170301','YYYYMMDD')
AND     T1.ORD_DT < TO_DATE('20170401','YYYYMMDD')
AND     T1.CUS_ID IN ('CUS_0010', 'CUS_0040', 'CUS_0050', 'CUS_0020', 'CUS_0030');

위 쿼리는 아래와같이 인라인-뷰 를 이용해 조인으로 처리하 수 있다