안녕하세요, 선배님들.
현재 누군가가 만들어둔 시스템을 유지보수 차원에서 인수받은 상태입니다.
엑셀 다운로드 기능을 붙이고, 검색조건 기능이 제대로 작동하는지 확인하던 도중에
연도와 월을 기준으로 출하 현황을 조회하는 쿼리를 보았는데,
1~12월까지 똑같은 조건으로 여러개의 스칼라 서브쿼리로 처리가 되어있더라구요...
(아래 쿼리에서 4~12월까지는 스크롤 압박으로 쿼리 문을 제외했습니다.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | SELECT I.COS_ITEM_CD ,I.COS_CTRY_NM ,( SELECT IFNULL( SUM (OOL2.COS_STRD_QTY),0) FROM COS_OORR OO2 INNER JOIN COS_OORR_LS OOL2 ON OO2.COS_REL_NUM = OOL2.COS_REL_NUM INNER JOIN COS_OBT_ORD_LS OL2 ON OOL2.COS_OOLS_SQ = OL2.COS_OOLS_SQ INNER JOIN COS_ITEM I2 ON OL2.COS_ITEM_CD = I2.COS_ITEM_CD WHERE OO2.COS_PROD_FG = '출고완료' AND OL2.COS_ITEM_CD = OL.COS_ITEM_CD AND DATE_FORMAT(OO2.COS_STRD_DAY, '%Y-%c' ) = CONCAT( '2020' , '-1' ) GROUP BY I2.COS_ITEM_CD ) AS JAN ,( SELECT IFNULL( SUM (OOL2.COS_STRD_QTY),0) FROM COS_OORR OO2 INNER JOIN COS_OORR_LS OOL2 ON OO2.COS_REL_NUM = OOL2.COS_REL_NUM INNER JOIN COS_OBT_ORD_LS OL2 ON OOL2.COS_OOLS_SQ = OL2.COS_OOLS_SQ INNER JOIN COS_ITEM I2 ON OL2.COS_ITEM_CD = I2.COS_ITEM_CD WHERE OO2.COS_PROD_FG = '출고완료' AND OL2.COS_ITEM_CD = OL.COS_ITEM_CD AND DATE_FORMAT(OO2.COS_STRD_DAY, '%Y-%c' ) = CONCAT( '2020' , '-2' ) GROUP BY I2.COS_ITEM_CD ) AS FEB ,( SELECT IFNULL( SUM (OOL2.COS_STRD_QTY),0) FROM COS_OORR OO2 INNER JOIN COS_OORR_LS OOL2 ON OO2.COS_REL_NUM = OOL2.COS_REL_NUM INNER JOIN COS_OBT_ORD_LS OL2 ON OOL2.COS_OOLS_SQ = OL2.COS_OOLS_SQ INNER JOIN COS_ITEM I2 ON OL2.COS_ITEM_CD = I2.COS_ITEM_CD WHERE OO2.COS_PROD_FG = '출고완료' AND OL2.COS_ITEM_CD = OL.COS_ITEM_CD AND DATE_FORMAT(OO2.COS_STRD_DAY, '%Y-%c' ) = CONCAT( '2020' , '-3' ) GROUP BY I2.COS_ITEM_CD ) AS MAR , SUM (OOL.COS_STRD_QTY) AS COS_STRD_QTY FROM COS_OORR OO INNER JOIN COS_OORR_LS OOL ON OO.COS_REL_NUM = OOL.COS_REL_NUM INNER JOIN COS_OBT_ORD_LS OL ON OOL.COS_OOLS_SQ = OL.COS_OOLS_SQ INNER JOIN COS_ITEM I ON OL.COS_ITEM_CD = I.COS_ITEM_CD INNER JOIN COS_OBT_ORD O ON OO.COS_OBT_ORD_CD = O.COS_OBT_ORD_CD LEFT OUTER JOIN COS_ACCT A ON O.COS_ACCT_CD = A.COS_ACCT_CD WHERE OO.COS_PROD_FG = '출고완료' AND DATE_FORMAT(OO.COS_STRD_DAY, '%Y' ) = '2020' GROUP BY I.COS_ITEM_CD |
앞의 쿼리는 성능이 떨어지는 쿼리라 생각해서 제가 변경한 쿼리는 다음과 같습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | SELECT I.COS_ITEM_CD AS '아이템 코드' , I.COS_CTRY_NM AS '아이템 이름' , DATE_FORMAT(OO.COS_STRD_DAY, '%Y-%m' ) AS '출고 년월' , ( CASE DATE_FORMAT(OO.COS_STRD_DAY, '%Y-%m' ) WHEN '2020-01' THEN IFNULL( SUM (OOL.COS_STRD_QTY), 0) END ) AS 'JAN' , ( CASE DATE_FORMAT(OO.COS_STRD_DAY, '%Y-%m' ) WHEN '2020-02' THEN IFNULL( SUM (OOL.COS_STRD_QTY), 0) END ) AS 'FEB' , ( CASE DATE_FORMAT(OO.COS_STRD_DAY, '%Y-%m' ) WHEN '2020-03' THEN IFNULL( SUM (OOL.COS_STRD_QTY), 0) END ) AS 'MAR' , ( CASE DATE_FORMAT(OO.COS_STRD_DAY, '%Y-%m' ) WHEN '2020-04' THEN IFNULL( SUM (OOL.COS_STRD_QTY), 0) END ) AS 'APR' , ( CASE DATE_FORMAT(OO.COS_STRD_DAY, '%Y-%m' ) WHEN '2020-05' THEN IFNULL( SUM (OOL.COS_STRD_QTY), 0) END ) AS 'MAY' , ( CASE DATE_FORMAT(OO.COS_STRD_DAY, '%Y-%m' ) WHEN '2020-06' THEN IFNULL( SUM (OOL.COS_STRD_QTY), 0) END ) AS 'JUN' , ( CASE DATE_FORMAT(OO.COS_STRD_DAY, '%Y-%m' ) WHEN '2020-07' THEN IFNULL( SUM (OOL.COS_STRD_QTY), 0) END ) AS 'JUL' , ( CASE DATE_FORMAT(OO.COS_STRD_DAY, '%Y-%m' ) WHEN '2020-08' THEN IFNULL( SUM (OOL.COS_STRD_QTY), 0) END ) AS 'AUG' , ( CASE DATE_FORMAT(OO.COS_STRD_DAY, '%Y-%m' ) WHEN '2020-09' THEN IFNULL( SUM (OOL.COS_STRD_QTY), 0) END ) AS 'SEP' , ( CASE DATE_FORMAT(OO.COS_STRD_DAY, '%Y-%m' ) WHEN '2020-10' THEN IFNULL( SUM (OOL.COS_STRD_QTY), 0) END ) AS 'OCT' , ( CASE DATE_FORMAT(OO.COS_STRD_DAY, '%Y-%m' ) WHEN '2020-11' THEN IFNULL( SUM (OOL.COS_STRD_QTY), 0) END ) AS 'NOV' , ( CASE DATE_FORMAT(OO.COS_STRD_DAY, '%Y-%m' ) WHEN '2020-12' THEN IFNULL( SUM (OOL.COS_STRD_QTY), 0) END ) AS 'DEC' , IFNULL( SUM (OOL.COS_STRD_QTY), 0) AS '전체 합계' FROM COS_OORR OO INNER JOIN COS_OORR_LS OOL ON OO.COS_REL_NUM = OOL.COS_REL_NUM INNER JOIN COS_OBT_ORD_LS OL ON OOL.COS_OOLS_SQ = OL.COS_OOLS_SQ INNER JOIN COS_ITEM I ON OL.COS_ITEM_CD = I.COS_ITEM_CD INNER JOIN COS_OBT_ORD O ON OO.COS_OBT_ORD_CD = O.COS_OBT_ORD_CD LEFT OUTER JOIN COS_ACCT A ON O.COS_ACCT_CD = A.COS_ACCT_CD WHERE OO.COS_PROD_FG = '출고완료' AND DATE_FORMAT(OO.COS_STRD_DAY, '%Y' ) = '2020' GROUP BY I.COS_ITEM_CD , I.COS_CTRY_NM , DATE_FORMAT(OO.COS_STRD_DAY, '%Y-%m' ) |
여기서 궁금한 것이 있습니다.
개별 조건은 CASE 문으로 처리하는 게 효율적이라고 배웠는데,
변경된 쿼리에서 CASE의 DATE_FORMAT(OO.COS_STRD_DAY, '%Y-%m')과
THEN의 IFNULL(SUM(OOL.COS_STR_QTY), 0)은 모두 동일하고,
다른 조건으로는 WHEN의 연도-월만 다르게 SELECT 하는 상황입니다.
다음의 쿼리문을 축약해서 사용할 수 있는 방법이 있을까요?
답변 미리 감사드립니다. ^^
1. GROUP BY 및 CASE 사용 문제
- GROUP BY 에서는 월이 빠져야 하고
- CASE(SUM) 이 아닌 SUM(CASE) 형태가 되어야 합니다.
2. 조건절 컬럼 가공 비효율
- 컬럼을 가공하여 조건에 맞추지 말고
- 조건을 가공하여 컬럼에 맞추세요.
3. 표준 쿼리 사용
- 알리아스에는 홑따옴표가 아닌 쌍따옴표 사용하세요.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | SELECT i.cos_item_cd AS "아이템 코드" , i.cos_ctry_nm AS "아이템 이름" --???, DATE_FORMAT(oo.cos_strd_day, '%Y-%m') AS "출고 년월" , IFNULL( SUM ( CASE DATE_FORMAT(oo.cos_strd_day, '%m' ) WHEN '01' THEN ool.cos_strd_qty END ), 0) JAN , IFNULL( SUM ( CASE DATE_FORMAT(oo.cos_strd_day, '%m' ) WHEN '02' THEN ool.cos_strd_qty END ), 0) FEB , IFNULL( SUM ( CASE DATE_FORMAT(oo.cos_strd_day, '%m' ) WHEN '03' THEN ool.cos_strd_qty END ), 0) MAR , IFNULL( SUM ( CASE DATE_FORMAT(oo.cos_strd_day, '%m' ) WHEN '04' THEN ool.cos_strd_qty END ), 0) APR , IFNULL( SUM ( CASE DATE_FORMAT(oo.cos_strd_day, '%m' ) WHEN '05' THEN ool.cos_strd_qty END ), 0) MAY , IFNULL( SUM ( CASE DATE_FORMAT(oo.cos_strd_day, '%m' ) WHEN '06' THEN ool.cos_strd_qty END ), 0) JUN , IFNULL( SUM ( CASE DATE_FORMAT(oo.cos_strd_day, '%m' ) WHEN '07' THEN ool.cos_strd_qty END ), 0) JUL , IFNULL( SUM ( CASE DATE_FORMAT(oo.cos_strd_day, '%m' ) WHEN '08' THEN ool.cos_strd_qty END ), 0) AUG , IFNULL( SUM ( CASE DATE_FORMAT(oo.cos_strd_day, '%m' ) WHEN '09' THEN ool.cos_strd_qty END ), 0) SEP , IFNULL( SUM ( CASE DATE_FORMAT(oo.cos_strd_day, '%m' ) WHEN '10' THEN ool.cos_strd_qty END ), 0) OCT , IFNULL( SUM ( CASE DATE_FORMAT(oo.cos_strd_day, '%m' ) WHEN '11' THEN ool.cos_strd_qty END ), 0) NOV , IFNULL( SUM ( CASE DATE_FORMAT(oo.cos_strd_day, '%m' ) WHEN '12' THEN ool.cos_strd_qty END ), 0) DEC , SUM (ool.cos_strd_qty) AS "전체 합계" FROM cos_oorr oo INNER JOIN cos_oorr_ls ool ON oo.cos_rel_num = ool.cos_rel_num INNER JOIN cos_obt_ord_ls ol ON ool.cos_ools_sq = ol.cos_ools_sq INNER JOIN cos_item i ON ol.cos_item_cd = i.cos_item_cd INNER JOIN cos_obt_ord o ON oo.cos_obt_ord_cd = o.cos_obt_ord_cd LEFT OUTER JOIN cos_acct a ON o.cos_acct_cd = a.cos_acct_cd WHERE oo.cos_prod_fg = '출고완료' AND oo.cos_strd_day >= CONCAT( '2020' , '-01-01' ) AND oo.cos_strd_day < DATE_ADD(CONCAT( '2020' , '-01-01' ), INTERVAL 1 YEAR ) GROUP BY i.cos_item_cd, i.cos_ctry_nm ; |