안녕하세요...표시해야 하는 항목이 고정일 경우 해당 정보들의 가장 최근 일자의 정보로 표시해야 하는데,
가져오는 방식에 대해 고민이 좀 되서 문의 드립니다.
/* 1번 방법 */
WITH TMP_A AS (
SELECT '001' AS DVSN, '과일' AS DVSN_NM FROM DUAL
UNION ALL SELECT '002' AS DVSN, '야채' AS DVSN_NM FROM DUAL
)
, TMP_B AS (
SELECT '001' AS DVSN, '001' AS COD, '수박' AS COD_NM, '20220710' AS IN_DY, 8000 AS PRIC FROM DUAL
UNION ALL SELECT '001' AS DVSN, '001' AS COD, '수박' AS COD_NM, '20220810' AS IN_DY, 5000 AS PRIC FROM DUAL
UNION ALL SELECT '001' AS DVSN, '002' AS COD, '참외' AS COD_NM, '20220605' AS IN_DY, 1000 AS PRIC FROM DUAL
UNION ALL SELECT '001' AS DVSN, '002' AS COD, '참외' AS COD_NM, '20220710' AS IN_DY, 1500 AS PRIC FROM DUAL
UNION ALL SELECT '002' AS DVSN, '003' AS COD, '배추' AS COD_NM, '20220510' AS IN_DY, 3000 AS PRIC FROM DUAL
UNION ALL SELECT '002' AS DVSN, '003' AS COD, '배추' AS COD_NM, '20220710' AS IN_DY, 4000 AS PRIC FROM DUAL
)
SELECT DVSN
, MAX(DVSN_NM) DVSN_NM
, MAX(COD_NM1) COD_NM1
, MAX(IN_DY1) IN_DY1
, MAX(PRIC1) PRIC1
, MAX(COD_NM2) COD_NM2
, MAX(IN_DY2) IN_DY2
, MAX(PRIC2) PRIC2
FROM (
SELECT A.DVSN
, A.DVSN_NM
, DECODE(COD, '001', IN_DY, '') IN_DY1
, DECODE(COD, '001', COD, '') COD1
, DECODE(COD, '001', COD_NM, '') COD_NM1
, DECODE(COD, '001', PRIC, '') PRIC1
, DECODE(COD, '002', IN_DY, '') IN_DY2
, DECODE(COD, '002', COD, '') COD2
, DECODE(COD, '002', COD_NM, '') COD_NM2
, DECODE(COD, '002', PRIC, '') PRIC2
FROM TMP_A A
, (SELECT * FROM (SELECT DVSN, COD, COD_NM, IN_DY, PRIC
, ROW_NUMBER() OVER(PARTITION BY DVSN, COD ORDER BY DVSN, COD, IN_DY DESC) RN
FROM TMP_B
WHERE DVSN = '001'
AND COD IN ('001', '002')
)
WHERE RN = 1
) B
WHERE A.DVSN = '001'
AND B.DVSN = A.DVSN
AND B.COD IN ('001', '002')
)
GROUP BY DVSN;
/* 2번 방법 */
WITH TMP_A AS (
SELECT '001' AS DVSN, '과일' AS DVSN_NM FROM DUAL
UNION ALL SELECT '002' AS DVSN, '야채' AS DVSN_NM FROM DUAL
)
, TMP_B AS (
SELECT '001' AS DVSN, '001' AS COD, '수박' AS COD_NM, '20220710' AS IN_DY, 8000 AS PRIC FROM DUAL
UNION ALL SELECT '001' AS DVSN, '001' AS COD, '수박' AS COD_NM, '20220810' AS IN_DY, 5000 AS PRIC FROM DUAL
UNION ALL SELECT '001' AS DVSN, '002' AS COD, '참외' AS COD_NM, '20220605' AS IN_DY, 1000 AS PRIC FROM DUAL
UNION ALL SELECT '001' AS DVSN, '002' AS COD, '참외' AS COD_NM, '20220710' AS IN_DY, 1500 AS PRIC FROM DUAL
UNION ALL SELECT '002' AS DVSN, '003' AS COD, '배추' AS COD_NM, '20220510' AS IN_DY, 3000 AS PRIC FROM DUAL
UNION ALL SELECT '002' AS DVSN, '003' AS COD, '배추' AS COD_NM, '20220710' AS IN_DY, 4000 AS PRIC FROM DUAL
)
SELECT DVSN
, DVSN_NM
, REGEXP_SUBSTR(CD1, '[^;]+', 1, 1) IN_DY1
, REGEXP_SUBSTR(CD1, '[^;]+', 1, 2) COD1
, REGEXP_SUBSTR(CD1, '[^;]+', 1, 3) COD_NM1
, REGEXP_SUBSTR(CD1, '[^;]+', 1, 4) PRIC1
, REGEXP_SUBSTR(CD2, '[^;]+', 1, 1) IN_DY2
, REGEXP_SUBSTR(CD2, '[^;]+', 1, 2) COD2
, REGEXP_SUBSTR(CD2, '[^;]+', 1, 3) COD_NM2
, REGEXP_SUBSTR(CD2, '[^;]+', 1, 4) PRIC2
FROM (
SELECT A.DVSN
, A.DVSN_NM
, (SELECT MAX(IN_DY||';'||COD||';'||COD_NM||';'||PRIC)
FROM TMP_B
WHERE DVSN = A.DVSN
AND COD = '001') CD1
, (SELECT MAX(IN_DY||';'||COD||';'||COD_NM||';'||PRIC)
FROM TMP_B
WHERE DVSN = A.DVSN
AND COD = '002') CD2
FROM TMP_A A
WHERE A.DVSN = '001'
);
다음과 같이 과일이라는 구분에 수박과 참외만 고정으로 최근정보를 칼럼으로 표시하는데요..
실제 TMP_B는 Row수가 상당히 많이 증가되고 있는 테이블입니다..
어떤 방식이 더 좋은건지 더 좋은 방식이 있는지 조언 부탁드립니다...감사합니다..꾸벅..
-- 1번 방식 좀 더 간결하게 : 불필요 인라인뷰 제거
SELECT a.dvsn
, a.dvsn_nm
, MIN(DECODE(b.cod, '001', b.cod_nm)) cod_nm1
, MIN(DECODE(b.cod, '001', b.in_dy )) in_dy1
, MIN(DECODE(b.cod, '001', b.pric )) pric1
, MIN(DECODE(b.cod, '002', b.cod_nm)) cod_nm2
, MIN(DECODE(b.cod, '002', b.in_dy )) in_dy2
, MIN(DECODE(b.cod, '002', b.pric )) pric2
FROM tmp_a a
, (SELECT dvsn, cod, cod_nm, in_dy, pric
, ROW_NUMBER() OVER(PARTITION BY dvsn, cod ORDER BY in_dy DESC) rn
FROM tmp_b b
WHERE dvsn = '001'
AND cod IN ('001', '002')
) b
WHERE a.dvsn = b.dvsn
AND b.rn = 1
GROUP BY a.dvsn, a.dvsn_nm
;
-- 2번 방식 비효율 개선 : 테이블 여러번 읽기 및 정규식 사용 제거
SELECT a.dvsn
, a.dvsn_nm
, MAX(DECODE(b.cod, '001', b.cod_nm)) cod_nm1
, MAX(DECODE(b.cod, '001', b.in_dy )) in_dy1
, SUBSTR(
MAX(DECODE(b.cod, '001', b.in_dy||b.pric)), 9) pric1
, MAX(DECODE(b.cod, '002', b.cod_nm)) cod_nm2
, MAX(DECODE(b.cod, '002', b.in_dy )) in_dy2
, SUBSTR(
MAX(DECODE(b.cod, '002', b.in_dy||b.pric)), 9) pric2
FROM tmp_a a
, tmp_b b
WHERE a.dvsn = '001'
AND a.dvsn = b.dvsn
AND b.cod IN ('001', '002')
GROUP BY a.dvsn, a.dvsn_nm
;
-- 3. MAX() KEEP() 이용 방법
SELECT a.dvsn
, a.dvsn_nm
, MAX(DECODE(b.cod, '001', b.cod_nm)) cod_nm1
, MAX(DECODE(b.cod, '001', b.in_dy )) in_dy1
, MAX(DECODE(b.cod, '001', b.pric )) pric1
, MAX(DECODE(b.cod, '002', b.cod_nm)) cod_nm2
, MAX(DECODE(b.cod, '002', b.in_dy )) in_dy2
, MAX(DECODE(b.cod, '002', b.pric )) pric2
FROM tmp_a a
, (SELECT dvsn
, cod
, cod_nm
, MAX(in_dy) in_dy
, MAX(pric) KEEP(DENSE_RANK LAST ORDER BY in_dy) pric
FROM tmp_b b
WHERE dvsn = '001'
AND cod IN ('001', '002')
GROUP BY dvsn, cod, cod_nm
) b
WHERE a.dvsn = b.dvsn
GROUP BY a.dvsn, a.dvsn_nm
;