mysql로 행렬 바꾸기를 못하겠습니다 ㅠ_ㅠ 0 11 3,486

by Tension [MySQL] [2016.03.23 11:18:08]


이미지 3.png (47,917Bytes)
이미지 5.png (15,656Bytes)

세로로 출력되는 부분을 가로로 바꾸고 싶은데 mysql 은 피봇이 안되서 못하고있습니다..

 

if(컬럼='1',컬럼,null) as 1,if(컬럼='2',컬럼,null) as 2,if(컬럼='3',컬럼,null) as 3,if(컬럼='4',컬럼,null) as 4

from T 

 

이런형식까지는 오라클 쿼리문 decode대체해서 만들었는데

저렇게 하면 계단식으로 데이터가 나옵니다

그걸 한 열로 만들려고 group by order by를 다해봐도.. 변하질않네요 ..

mysql 가로로 변환하는 방법이있다면 알려주시면 감사하겠습니다..

by swlee [2016.03.23 11:25:49]
select col1,col2
     , min(if(컬럼='1',컬럼)) as 1
     , min(if(컬럼='2',컬럼)) as 2
     , min(if(컬럼='3',컬럼)) as 3
     , min(if(컬럼='4',컬럼)) as 4
from T 	
group by col1, col2

 


by 마농 [2016.03.23 11:28:13]
SELECT col1, col2
     , MIN(CASE 컬럼 WHEN '1' THEN 컬럼 END) AS "1"
     , MIN(CASE 컬럼 WHEN '2' THEN 컬럼 END) AS "2"
     , MIN(CASE 컬럼 WHEN '3' THEN 컬럼 END) AS "3"
     , MIN(CASE 컬럼 WHEN '4' THEN 컬럼 END) AS "4"
  FROM t  
 GROUP BY col1, col2
;

 


by Tension [2016.03.23 11:46:49]

두분께서 말씀하신 대로 해도 글 수정해서 추가된 이미지 대로 피라미드가 나옵니다..

말씀하신 col1,col2가 컬럼이름을 말씀하시는거같아서 이렇게 만들었는데 

제가 뭔가 부족해서 빠뜨린거같습니다

전문 올려드립니다 (__)

	select s.date,s.rank,
		MIN(case s.date when '2016-03-01' then s.rank end) as '1',
		MIN(case s.date when '2016-03-02' then s.rank end) as '2',
		MIN(case s.date when '2016-03-03' then s.rank end) as '3',
		MIN(case s.date when '2016-03-04' then s.rank end) as '4',				
		MIN(case s.date when '2016-03-05' then s.rank end) as '5',
		MIN(case s.date when '2016-03-06' then s.rank end) as '6',
		MIN(case s.date when '2016-03-07' then s.rank end) as '7',
		MIN(case s.date when '2016-03-08' then s.rank end) as '8',
		MIN(case s.date when '2016-03-09' then s.rank end) as '9',
		MIN(case s.date when '2016-03-10' then s.rank end) as '10',
		MIN(case s.date when '2016-03-11' then s.rank end) as '11',
		MIN(case s.date when '2016-03-12' then s.rank end) as '12',
		MIN(case s.date when '2016-03-13' then s.rank end) as '13',
		MIN(case s.date when '2016-03-14' then s.rank end) as '14',
		MIN(case s.date when '2016-03-15' then s.rank end) as '15',				
		MIN(case s.date when '2016-03-16' then s.rank end) as '16',
		MIN(case s.date when '2016-03-17' then s.rank end) as '17',
		MIN(case s.date when '2016-03-18' then s.rank end) as '18',
		MIN(case s.date when '2016-03-19' then s.rank end) as '19',
		MIN(case s.date when '2016-03-20' then s.rank end) as '20',
		MIN(case s.date when '2016-03-21' then s.rank end) as '21',
		MIN(case s.date when '2016-03-22' then s.rank end) as '22',
		MIN(case s.date when '2016-03-23' then s.rank end) as '23',
		MIN(case s.date when '2016-03-24' then s.rank end) as '24',
		MIN(case s.date when '2016-03-25' then s.rank end) as '25',				
		MIN(case s.date when '2016-03-26' then s.rank end) as '26',
		MIN(case s.date when '2016-03-27' then s.rank end) as '27',
		MIN(case s.date when '2016-03-28' then s.rank end) as '28',
		MIN(case s.date when '2016-03-29' then s.rank end) as '29',
		MIN(case s.date when '2016-03-30' then s.rank end) as '30',
		MIN(case s.date when '2016-03-31' then s.rank end) as '31'
FROM (
SELECT DATE_FORMAT(DATE,'%Y-%m-%d') AS DATE, rank
FROM(
SELECT a.dt AS DATE, ROUND(COUNT(B.RANK)/10*100,2) AS rank
FROM (
SELECT dt + INTERVAL lv-1 DAY dt
FROM (
SELECT ordinal_position lv
, CONCAT('201603', '01') dt
FROM information_schema.columns
WHERE table_schema = 'mysql' AND table_name = 'user'
) a
WHERE lv <= DAY(LAST_DAY(dt))
) a
LEFT JOIN (
SELECT a.rank AS rank, DATE_FORMAT(rank_date, '%Y-%m-%d') AS rank_date,b.info_goalrank
FROM keyword_record AS a
JOIN client_collect_info AS b
WHERE a.client_collect_seq = b.client_collect_seq AND a.client_collect_seq =544 AND HOUR(a.rank_date) >=9 AND HOUR(a.rank_date) <=18 AND a.rank <=b.info_goalrank AND a.rank !=0
) b ON a.dt = b.rank_date
GROUP BY A.DT) AS ex) s
group by s.date,s.rank

 


by 마농 [2016.03.23 12:27:38]

Group By 항목이 잘못 되었네요.
조건절에 사용하는 항목(date)은 Group By 에서 빠져야죠.


by Tension [2016.03.23 12:44:14]

음.. 그렇게 해보니 이해가 되었습니다 

그러나 rank항목이 그룹이 하나로 되질 않아서 

한줄로 정렬이 되지 않고 같은 숫자별로되기때문에 

 

동일 퍼센트끼리만 되었습니다 글에 이미지 첨부해드립니다 ..


by Tension [2016.03.23 12:53:59]

오 같은 데이타의 컬럼을 임의로 만들어서 그놈을 group by 시켜서 해결했습니다 감사합니다 (__)


by 마농 [2016.03.23 13:16:53]

아예 Group By 자체를 빼면 됩니다.

또 information_schema.columns 를 이용한 아우터 조인도 필요 없습니다.


by 마농 [2016.03.23 13:30:05]

지난번 질문에서 비효율적인 부분들을 개선한 쿼리를 제시해 드렸는데...
전혀 적용을 안하셨네요. ㅠ,.ㅜ
1. ROUND(COUNT(b.rank)/10*100,2) 에서
  - COUNT(b.rank) 는 COUNT(*) 로 바꿔도 결과 동일하고요, 더 효율적이죠.
  - /10*100 부분은 *10 과 동일하고요
  - ROUND(, 2) 부분은 안해도 되는 것이죠.
  - 결론은 COUNT(*)*10 으로 바꾸면 되는 거죠.
2. information_schema.columns 를 이용한 아우터 조인은?
  - 날짜별로 아래로 나열할 때 필요한 스킬이었죠
  - 옆으로 나열할 때는 사용할 필요가 없죠

SELECT COUNT(CASE dd WHEN '01' THEN 1 END)*10.00 "01"
     , COUNT(CASE dd WHEN '02' THEN 1 END)*10.00 "02"
     , COUNT(CASE dd WHEN '03' THEN 1 END)*10.00 "03"
     , COUNT(CASE dd WHEN '04' THEN 1 END)*10.00 "04"
     , COUNT(CASE dd WHEN '05' THEN 1 END)*10.00 "05"
     , COUNT(CASE dd WHEN '06' THEN 1 END)*10.00 "06"
     , COUNT(CASE dd WHEN '07' THEN 1 END)*10.00 "07"
     , COUNT(CASE dd WHEN '08' THEN 1 END)*10.00 "08"
     , COUNT(CASE dd WHEN '09' THEN 1 END)*10.00 "09"
     , COUNT(CASE dd WHEN '10' THEN 1 END)*10.00 "10"
     , COUNT(CASE dd WHEN '11' THEN 1 END)*10.00 "11"
     , COUNT(CASE dd WHEN '12' THEN 1 END)*10.00 "12"
     , COUNT(CASE dd WHEN '13' THEN 1 END)*10.00 "13"
     , COUNT(CASE dd WHEN '14' THEN 1 END)*10.00 "14"
     , COUNT(CASE dd WHEN '15' THEN 1 END)*10.00 "15"
     , COUNT(CASE dd WHEN '16' THEN 1 END)*10.00 "16"
     , COUNT(CASE dd WHEN '17' THEN 1 END)*10.00 "17"
     , COUNT(CASE dd WHEN '18' THEN 1 END)*10.00 "18"
     , COUNT(CASE dd WHEN '19' THEN 1 END)*10.00 "19"
     , COUNT(CASE dd WHEN '20' THEN 1 END)*10.00 "20"
     , COUNT(CASE dd WHEN '21' THEN 1 END)*10.00 "21"
     , COUNT(CASE dd WHEN '22' THEN 1 END)*10.00 "22"
     , COUNT(CASE dd WHEN '23' THEN 1 END)*10.00 "23"
     , COUNT(CASE dd WHEN '24' THEN 1 END)*10.00 "24"
     , COUNT(CASE dd WHEN '25' THEN 1 END)*10.00 "25"
     , COUNT(CASE dd WHEN '26' THEN 1 END)*10.00 "26"
     , COUNT(CASE dd WHEN '27' THEN 1 END)*10.00 "27"
     , COUNT(CASE dd WHEN '28' THEN 1 END)*10.00 "28"
     , COUNT(CASE dd WHEN '29' THEN 1 END)*10.00 "29"
     , COUNT(CASE dd WHEN '30' THEN 1 END)*10.00 "30"
     , COUNT(CASE dd WHEN '31' THEN 1 END)*10.00 "31"
  FROM (SELECT DATE_FORMAT(rank_date, '%d') AS dd
          FROM keyword_record       AS a
          JOIN client_collect_inf.o AS b
            ON a.client_collect_seq = b.client_collect_seq
           AND a.rank <= b.info_goalrank
         WHERE a.client_collect_seq = 544
           AND HOUR(a.rank_date) >=  9
           AND HOUR(a.rank_date) <= 18
           AND a.rank != 0
           AND DATE_FORMAT(rank_date, '%Y%m') = '201603'
        ) a
;

 


by Tension [2016.03.23 13:43:18]

아 ㅠ_ㅠ 지금 view단에서 뿌려줄때 속도를 줄이기 위해서 이것저것 바꿔보는 중이라 

저번에 답변해주신부분 ( 여러개를 뿌리는 방법) 킵해두고 

 

이번에는 가로로 만드는 부분 을 생각하던터라 예전소스로 질문을 드렸습니다 

 

이젠 두개 조합해서 가로로 여러개 하는방법을 생각해보겠습니다..

 

조언을 받을 사람이 없는 상황이라 머리싸매다 정 안되면 여기에 여쪄보곤하는데

 

올리적마다 많이 알려주셔서 감사합니다 (__) 

 

 


by Tension [2016.03.23 13:44:58]

아! 그리고 round 같은 경우는 소수점을 꼭 나타내야 하는부분이라서 그렇게 했던 기억이 있습니다.


by 마농 [2016.03.23 13:58:56]

round 가 소수점 자리수 맞추기 위한 거였군요? 흠...

그냥 * 10.00 하면 되겠습니다.

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