그룹별 카운트 쿼리 질문 0 2 1,426

by 그루비 [SQL Query] [2018.06.20 19:39:21]


SELECT
	chno,
	channel,
	MAX(viewcnt),
	MAX(continuecnt),
	MAX(stopcnt)
FROM
	(
		SELECT
			channel,
			NVL(DECODE(channel, '7', 1, DECODE(channel, '11', 2, DECODE(channel, '13', 3, 4))), 0) AS chno,
			NVL(COUNT(*), 0) AS viewcnt,
			0 AS continuecnt,
			0 AS stopcnt
		FROM
			tvreport
		WHERE
			TO_CHAR(TO_DATETIME(senddate, 'yyyymmdd'), 'yyyy') = '2018'
			AND TO_CHAR(TO_DATETIME(senddate, 'yyyymmdd'), 'mm') = '05'
			AND adminid = '1'
			AND hostcode IN ('7','11','13',	'17')
			AND delFlag = 0
		GROUP BY
			channel
		UNION ALL
		SELECT
			channel,
			NVL(DECODE(channel, '7', 1, DECODE(channel, '11', 2, DECODE(channel, '13', 3, 4))), 0) AS chno,
			0 AS viewcnt,
			NVL(COUNT(*), 0) AS continuecnt,
			0 AS stopcnt
		FROM
			tvreport
		WHERE
			TO_CHAR(TO_DATETIME(senddate, 'yyyymmdd'), 'yyyy') = '2018'
			AND TO_CHAR(TO_DATETIME(senddate, 'yyyymmdd'), 'mm') = '05'
			AND viewplace = '집'
			AND chcode IN (	'7','11','13','17')
			AND delFlag = 0
		GROUP BY
			channel
	)
GROUP BY channel,chno
ORDER BY	chno ASC

-----------------------------------------------------------------

 

채널별로 숫자를 새려고 합니다.

실제로는 조건이 2개 더있는데 너무 길어서 줄여서 올립니다.

하다보니깐 먼가 복잡해지고 쿼리도 2초나 걸려서 다른 방안이 있을까 싶어서 질문드리려고 합니다.

 

채널이 4개가 모두 나와야 하는데 카운트가 없는건 안나옵니다.

이럴떄 어떤걸 해야 할까요??

by 마농 [2018.06.21 10:42:55]

이상한 부분이 있네요.
1. TO_DATETIME 은 뭔가요? 오라클이 아닌 듯 하네요?
  - 컬럼을 가공하여 조건값에 맞추는 것보다는
  - 컬럼은 그대로 두고 조건을 가공하여 컬럼에 맞추는게 좋습니다.
  - senddate 의 타입과 DBMS 를 알야야 할 것 같네요.
  - senddate BETWEEN '20180501' AND '20180531' 형태가 되어야 합니다.
  - 우변의 조건값은 senddate 타입에 맞게 변환되어야 하구요.
2. 조건절이 각각인데...
  - DECODE 에서는 channel 을 사용하고
  - 1번쿼리 조건에서는 hostcode 를 사용하고
  - 2번쿼리 조건에서는 chcode 를 사용하고 있네요?
  - 조건값은 동일하게 ('7','11','13', '17') 인 듯 한데?
  - 컬럼은 제각각이네요?
  - 3개 컬럼이 다 다른건가요?


by 마농 [2018.06.21 11:42:28]
SELECT a.chno
     , a.channel
     , NVL(b.viewcnt    , 0) viewcnt
     , NVL(b.continuecnt, 0) continuecnt
     , NVL(b.stopcnt    , 0) stopcnt
  FROM (SELECT 1 chno, '7' channel FROM dual
        UNION ALL SELECT 2, '11' FROM dual
        UNION ALL SELECT 3, '13' FROM dual
        UNION ALL SELECT 4, '17' FROM dual
        ) a
  LEFT OUTER JOIN
       (SELECT channel
             , COUNT(DECODE(adminid  , '1' , 1)) AS viewcnt
             , COUNT(DECODE(viewplace, '집', 1)) AS continuecnt
             , COUNT(...)                        AS stopcnt
          FROM tvreport
         WHERE senddate LIKE '2018'||'05'||'%'
           AND channel IN ('7', '11', '13', '17')
           AND delFlag = 0
           AND (  adminid   = '1'  -- viewcnt
               OR viewplace = '집' -- continuecnt
               OR ...              -- stopcnt
               )
         GROUP BY channel
        ) b
    ON a.channel = b.channel
 ORDER BY chno
;

 

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입