union all 종일 해보다 안되서 다시 질문 드립니다.. 0 4 1,439

by Tension [2016.04.08 16:08:30]


이러한 쿼리가 한개가 아니라서 고쳐볼려 노력했지만 똑같이 에러가 떠서 다시 재질문 드립니다 ㅠ_ㅠ

 

 

 

 


 select client_collect_seq,h09,h10,h11,h12,h13,h14,h15,h16,h17,h18,h24,client_name,info_platform,info_keyword,info_url,info_title,info_startday,info_endday from 
				 (select  seq,
					Max(case time when '09' then rank end) as 'h09',
					Max(case time when '10' then rank end) as 'h10',
					Max(case time when '11' then rank end) as 'h11',
					MAx(case time when '12' then rank end) as 'h12',
					max(case time when '13' then rank end) as 'h13',
					max(case time when '14' then rank end) as 'h14',
					max(case time when '15' then rank end) as 'h15',				
					max(case time when '16' then rank end) as 'h16',
					max(case time when '17' then rank end) as 'h17',
					max(case time when '18' then rank end) as 'h18'
					from(
							select a.time,b.rank,11 as seq
                            from (
                            SELECT '09' time
					        UNION ALL SELECT '10'
					        UNION ALL SELECT '11'
					        UNION ALL SELECT '12'
					        UNION ALL SELECT '13'
					        UNION ALL SELECT '14'
					        UNION ALL SELECT '15'
					        UNION ALL SELECT '16'
					        UNION ALL SELECT '17'
					        UNION ALL SELECT '18'
					       	) as a
								 left outer join(	
								 select rank,hour(rank_date) as time				
								from keyword_record
							where DATE_FORMAT(rank_date,'%Y-%m-%d') like '2016-04-01'
							and client_collect_seq=11) as b
							on a.time = b.time
						) as v
						group by seq) as b inner join client_collect_info inner join (
                        
                         select count(*) as h24 ,11 as seq from (
                            SELECT '09' time
					        UNION ALL SELECT '10'
					        UNION ALL SELECT '11'
					        UNION ALL SELECT '12'
					        UNION ALL SELECT '13'
					        UNION ALL SELECT '14'
					        UNION ALL SELECT '15'
					        UNION ALL SELECT '16'
					        UNION ALL SELECT '17'
					        UNION ALL SELECT '18'
					       	) as a
								 left outer join(	
								 select rank,hour(rank_date) as time				
								from keyword_record
							where DATE_FORMAT(rank_date,'%Y-%m-%d') like '2016-04-01'
							and client_collect_seq=11) as b
							on a.time = b.time
                       ) as c
                        where client_collect_info.client_collect_seq = b.seq
                        and b.seq = c.seq

 

세로를 가로로 변환시켜 한행만 나오는 쿼리 인데

 

이걸 for문으로 돌려서 Union all 시켜서 출력시키려 합니다

 

 

select * from (

T

union all

T

union all

T

..

..

..

) as A

 

이러한 식으로 가려 합니다

 

그러나 문제점은 

 

단 몇개의 T를 반복이시면 문제가 되지 않지만

 

어느정도의 T의 반복문이 넘어가면 invalid use of group function이 뜹니다

 

이건 좀 랜덤으로 쿼리를 조금 바꾸면 30개에서 나고 

어떨땐 20개 어떨땐 50개 이런식으로 가변적으로 에러나는 타이밍이 달라집니다..

 

group function 이라 하여 Min 을 안쓰는 방법으로 행렬을 변경하고 싶지만 그건 안되는건지 제가 못하는건지 

 

방법에 실패 하였고 

 

맨아래 group by 절을 빼고 만들어 봤지만 그래도 오류는 똑같이 발생하였습니다

 

제쿼리의 문제인지 

 

아니면 union all을 사용할때 뭔가 제약조건이 붙는것인지 잘모르겠습니다

 

미리 감사의말씀드립니다 (__)

 

by jkson [2016.04.08 17:52:18]

mysql 쓰시는 건가요?

오라클에서는 union all을 많이 한다고 오류가 나는 건 본적이 없는데..

뭔가 다른 이유이지 않나 싶네요.

적어주신 쿼리가 union all을 해주는 T인 건가요?

그렇다면 여러 조건 값을 받아서 각각의 결과를 합쳐주려고 union all 하시는 것 같은데..

이게 상당히 비효율적인게 조건이 엄청 늘어나면 쿼리 전체 길이도 길어질테고

그러면 파싱에도 무리가 있을 것이고 좋은 방법 같지는 않아요.

차라리 조건문만 유동적으로 변경되게 수정하시는 게 나아보이는데요..

 

위 쿼리에서

((DATE_FORMAT(rank_date,'%Y-%m-%d') like '2016-04-01' and client_collect_seq=11)

or (DATE_FORMAT(rank_date,'%Y-%m-%d') like '2016-04-02' and client_collect_seq=11)
or (DATE_FORMAT(rank_date,'%Y-%m-%d') like '2016-04-03' and client_collect_seq=11)
)

이런식으로요.

제가 이해한 게 맞는지 모르겠네요.

 

 


by Tension [2016.04.08 18:03:45]

네 MYSQL 입니다...

 

WHERE 절에서 유동적이게 OR 로 하게 되면 행렬바꾸기가 불가능해져서 저렇게 하고있습니다..

 

아무리 쿼리를 변경을 해보아도 오류가 그치질 않네요 ㅠㅠ


by Tension [2016.04.08 18:07:03]

이게 똑같은 반복인데 어느정도가 돌면 에러가 나는지 알수가 없네요 .. 

 

UNION ALL에 뭔가 제약사항이 있는가도 싶고..ㅠ


by 마농 [2016.04.11 09:17:48]

1. 조건절을 바꿔가며 UNION ALL 할 필요 없습니다.
  - 조건을 한꺼번에 주고 GROUP BY 하면 됩니다.
2. 피벗(행을 열로) 하기 위해 시간 집합을 따로 조인할 필요는 없습니다.
  - 조인 없이 바로 피벗 가능 합니다.
  - 피벗 따로 카운트 따로 구할 필요도 없구요.

SELECT a.client_collect_seq
     , b.h09, b.h10, b.h11, b.h12, b.h13, b.h14, b.h15, b.h16, b.h17, b.h18
     , b.h24
     , a.client_name
     , a.info_platform
     , a.info_keyword
     , a.info_url
     , a.info_title
     , a.info_startday
     , a.info_endday
  FROM client_collect_info a
 INNER JOIN 
       (SELECT client_collect_seq
             , MAX(CASE HOUR(rank_date) WHEN  9 THEN rank END) h09
             , MAX(CASE HOUR(rank_date) WHEN 10 THEN rank END) h10
             , MAX(CASE HOUR(rank_date) WHEN 11 THEN rank END) h11
             , MAX(CASE HOUR(rank_date) WHEN 12 THEN rank END) h12
             , MAX(CASE HOUR(rank_date) WHEN 13 THEN rank END) h13
             , MAX(CASE HOUR(rank_date) WHEN 14 THEN rank END) h14
             , MAX(CASE HOUR(rank_date) WHEN 15 THEN rank END) h15
             , MAX(CASE HOUR(rank_date) WHEN 16 THEN rank END) h16
             , MAX(CASE HOUR(rank_date) WHEN 17 THEN rank END) h17
             , MAX(CASE HOUR(rank_date) WHEN 18 THEN rank END) h18
             , COUNT(*) h24
          FROM keyword_record
         WHERE DATE_FORMAT(rank_date,'%Y-%m-%d') LIKE '2016-04-01'
           AND HOUR(rank_date) BETWEEN 9 AND 18
           AND client_collect_seq IN (11, 12, 13, 14, 15)
         GROUP BY client_collect_seq
        ) b
    ON a.client_collect_seq = b.client_collect_seq
;

 

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