by 바카니 [SQL Query] postgresql query db [2020.04.23 11:01:05]
안녕하세요. 답변 주신다면 정말 감사하겠습니다.
* 질문 1. 아래 현재 쿼리에서 서브쿼리 이용해서 case 문으로 감싸서 가져오고 있는 쿼리 방식의 속도 개선을 위해 어떻게 바꿀 수 있을까요?
(덧붙임 내용 :
각 where 조건의 값에 맞춰서 값을 가져오고 있는데, 조건이 건수를 이용해서 값을 판별하여 case 문을 주는거라
일단 이렇게는 짜놨는데...속도가 문제네요. )
* 현재 쿼리
select
<foreach collection="time" item="item" separator=",">
case
when (select count(1) from tb_test_result2 where use_yn = 'Y' and line_no = #{line_no} and prod_sapcode = #{prod_sapcode} and to_char(test_date, 'yyyymmddhh24') = to_char(now(), 'yyyymmdd')||#{item.cd_id})<![CDATA[<]]>10 or #{item.cd_id}<![CDATA[>]]>to_char(now(), 'hh24') then 'F'
when (select count(1) from tb_error_act_ht where use_yn = 'Y' and act_finish_yn = 'N' and to_char(error_sdate, 'yyyymmddhh24') = to_char(now(), 'yyyymmdd')||#{item.cd_id} and line_no = #{line_no} and prod_sapcode = #{prod_sapcode})<![CDATA[>]]>1 then 'RR'
when (select count(1) from tb_error_act_ht where use_yn = 'Y' and act_finish_yn = 'N' and to_char(error_sdate, 'yyyymmddhh24') = to_char(now(), 'yyyymmdd')||#{item.cd_id} and line_no = #{line_no} and prod_sapcode = #{prod_sapcode})<![CDATA[>]]>0 then 'R'
when (select count(1) from tb_error_act_ht where use_yn = 'Y' and act_finish_yn = 'Y' and to_char(error_sdate, 'yyyymmddhh24') = to_char(now(), 'yyyymmdd')||#{item.cd_id} and line_no = #{line_no} and prod_sapcode = #{prod_sapcode})<![CDATA[>]]>0 then 'C'
when (select count(1) from tb_test_result2 where use_yn = 'Y' and line_no = #{line_no} and prod_sapcode = #{prod_sapcode} and to_char(test_date, 'yyyymmddhh24') = to_char(now(), 'yyyymmdd')||#{item.cd_id})<![CDATA[>]]>10 and #{item.cd_id}||'00'<![CDATA[<=]]>to_char(now(), 'hh2400') and #{item.cd_id}||'59'<![CDATA[>=]]>to_char(now(), 'hh2400') then 'GG'
else 'G' end as h${item.cd_id}
</foreach>
가독성을 위해 이미지도 첨부하겠습니다!!!
SELECT MIN(CASE h WHEN 9 THEN v END) h09 , MIN(CASE h WHEN 10 THEN v END) h10 , MIN(CASE h WHEN 11 THEN v END) h11 , MIN(CASE h WHEN 12 THEN v END) h12 , MIN(CASE h WHEN 13 THEN v END) h13 , MIN(CASE h WHEN 14 THEN v END) h14 , MIN(CASE h WHEN 15 THEN v END) h15 , MIN(CASE h WHEN 16 THEN v END) h16 , MIN(CASE h WHEN 17 THEN v END) h17 , MIN(CASE h WHEN 18 THEN v END) h18 , MIN(CASE h WHEN 19 THEN v END) h19 , MIN(CASE h WHEN 20 THEN v END) h20 , MIN(CASE h WHEN 21 THEN v END) h21 FROM (SELECT h.h , CASE WHEN h.h > DATE_PART('hour', now()) THEN 'F' WHEN COALESCE(a.cnt_1, 0) < 10 THEN 'F' WHEN COALESCE(b.cnt_n, 0) > 1 THEN 'RR' WHEN COALESCE(b.cnt_n, 0) > 0 THEN 'R' WHEN COALESCE(b.cnt_y, 0) > 0 THEN 'C' WHEN COALESCE(a.cnt_1, 0) > 10 AND h.h = DATE_PART('hour', now()) THEN 'GG' ELSE 'G' END v FROM generate_series(9, 21) h(h) LEFT OUTER JOIN (SELECT DATE_PART('hour', test_date) h , COUNT(*) cnt_1 FROM tb_test_result2 WHERE use_yn = 'Y' AND line_no = #{line_no} AND prod_sapcode = #{prod_sapcode} -- AND TO_CHAR(test_date, 'yyyymmdd') = TO_CHAR(NOW(), 'yyyymmdd') AND test_date >= DATE_TRUNC('day', NOW()) AND test_date < DATE_TRUNC('day', NOW() + INTERVAL '1 day') GROUP BY DATE_PART('hour', test_date) ) a ON h.h = a.h LEFT OUTER JOIN (SELECT DATE_PART('hour', error_sdate) h , COUNT(CASE WHEN act_finish_yn = 'N' THEN 1 END) cnt_n , COUNT(CASE WHEN act_finish_yn = 'Y' THEN 1 END) cnt_y FROM tb_error_act_ht WHERE use_yn = 'Y' AND line_no = #{line_no} AND prod_sapcode = #{prod_sapcode} -- AND TO_CHAR(error_sdate, 'yyyymmdd') = TO_CHAR(NOW(), 'yyyymmdd') AND error_sdate >= DATE_TRUNC('day', NOW()) AND error_sdate < DATE_TRUNC('day', NOW() + INTERVAL '1 day') GROUP BY DATE_PART('hour', error_sdate) ) b ON h.h = b.h ) c ;