2014-06-10 3 views
1

다음 테이블이 있습니다. pk1은 기본 키이며 고유합니다. t1은 이벤트 시간이고, e1은 이벤트 유형이며, ek2는 동일한 ek2에 대한 이벤트 키이므로, 여러 이벤트가있을 수 있습니다.타임 스탬프가 포함 된 MySQL 피벗 테이블 쿼리

샘플 데이터는 여기에 테이블을 복제하려면 여기

pk1, t1, e1, ek2 
10001, 14/02/2014 01:00:00, banner, a0001 
10002, 15/02/2014 02:00:00, search, a0001 
10003, 15/02/2014 04:00:00, search, a0001 
10004, 14/02/2014 01:00:00, banner, a0002 
10005, 15/02/2014 02:00:00, search, a0002 

된 SQL입니다.

CREATE TABLE Table1 (`pk1` int, `t1` datetime, `e1` varchar(6), `ek2` varchar(5)); 
INSERT INTO Table1 (`pk1`, `t1`, `e1`, `ek2`) 
VALUES (10001, '2015-02-02 09:00:00', 'banner', 'a0001'), 
(10002, '2015-03-02 10:00:00', 'search', 'a0001'), 
(10003, '2015-03-02 12:00:00', 'search', 'a0001'), 
(10004, '2015-02-02 09:00:00', 'banner', 'a0002'), 
(10005, '2015-03-02 10:00:00', 'search', 'a0002'); 

원하는 결과는 원본 DB에 단일 이벤트 당 최대 15 개의 이벤트가 있습니다.

event key, 1st event, 2nd event, 3rd event, ... 
a0001, banner, search, search 
a0002, banner, search 

시행 착오를 거친 후 1 차 4면을 고려한 다음 쿼리를 작성합니다. 버그가 없다면 15 번째 이벤트 (et15)로 확장 할 것입니다.

SELECT ek2, 
    MAX(case when pk1 =1 THEN e1 END) as et1, 
    MAX(case when pk1 =2 THEN e1 END) as et2, 
    MAX(case when pk1 =3 THEN e1 END) as et3, 
    MAX(case when pk1 =4 THEN e1 END) as et4 
FROM (SELECT t0.pk1, t0.e1, t0.ek2 
    FROM Table1 AS t0 
    LEFT JOIN Table1 AS t1 ON t0.ek2=t1.ek2 AND t1.pk1>t0.pk1 
    where t1.pk1 is null 
    ORDER by t0.t1) as rn 
GROUP by ek2; 

하위 쿼리는 각 이벤트 (ek2)의 최대 타임 스탬프를 가져 오려고 시도합니다. 그리고 Simple Query to Grab Max Value for each ID에 참조하지만 결과는 내 코드에 문제가 있습니다 이것이

a0001, null, null, null, null    
a0002, null, null, null, null 

입니까?

1 업데이트 :. (Ravinder의 입력 주셔서 감사합니다), 또한 나는, 지정된 이벤트 (ei2) 각 sub_event (PK1)에 대한 행 번호 (또는 인덱스의 종류를 추가하기 위해 다음과 같이 업데이트 코드를 생각

여전히
SELECT ek2, 
    MAX(case when row_n =1 THEN e1 END) as et1, 
    MAX(case when row_n =2 THEN e1 END) as et2, 
    MAX(case when row_n =3 THEN e1 END) as et3, 
    MAX(case when row_n =4 THEN e1 END) as et4 
FROM (SELECT t0.pk1, t0.e1, t0.ek2, @curRow := @curRow + 1 AS row_n 
    FROM Table1 AS t0 
    JOIN (select @curRow :=0) r 
    LEFT JOIN Table1 AS t1 ON t0.ek2=t1.ek2 AND t1.pk1>t0.pk1 
    where t1.pk1 is NOT null 
    ORDER by t0.t1) as rn 
GROUP by ek2; 

이것의 결과는 것, 조금 더 가까이 있지만 디버깅이 필요합니다.

a0001, banner, banner, search, (null) 
a0002, (null), (null), (null), banner 

갱신 2. Row number per group in mysql을 참조하면, 나는이 업데이트 쿼리. 더 행을 추가 할 관리하지 않습니다.

,
SELECT ek2, 
    MAX(case when row_n =1 THEN e1 END) as et1, 
    MAX(case when row_n =2 THEN e1 END) as et2, 
    MAX(case when row_n =3 THEN e1 END) as et3, 
    MAX(case when row_n =4 THEN e1 END) as et4 
FROM (SELECT t0.pk1, t0.e1, t0.ek2, t0.t1, 
     (CASE t0.ek2 
      WHEN @curType 
      THEN @curRow := @curRow + 1 
      ELSE @curRow := 1 AND @curType := t0.ek2 END 
     ) + 1 AS row_n 
    FROM Table1 AS t0 
    LEFT JOIN Table1 AS t1 ON t0.ek2=t1.ek2 AND t1.pk1>t0.pk1 
    join (select @curRow :=0, @curType := '') r 
    where t1.pk1 is NOT null 
    ORDER by t0.ek2,row_n) as rn 
GROUP by ek2; 

결과는 howerver 당신은 두번째 이벤트가 A0001 배너 및 A0002에 대한 널 볼, 하나의 추가 문제가 있습니다,이

a0001, banner, banner, search, (null) 
a0002, banner, (null), (null), (null) 

그것은 내가 원하는 것과 매우 가깝습니다. 올바른 aoud1을 검색하고 a0002도 검색하십시오. 여기서 뭐가 틀린거야?

나는 where t1.pk1 is NOT null 절을

a0001, banner, banner, search, search 
a0002, banner, search, (null), (null) 

를 제거하고 여전히 정확하지 않으면.

추가 질문. 이벤트가 가변적 인 경우 동적 이벤트로 만들 수 있습니까? 마치 MySQL pivot row into dynamic number of columns처럼?

먼저 관심을 가져 주셔서 감사합니다.

건배,

rc.

+0

문제는''t1.pk1이 null ''인 곳에 있어야합니다. 나는 그것이 ''not null ''이어야한다고 생각한다. 그렇지 않으면 하위 쿼리는 항상 'NULL'값을 반환합니다. –

+0

당신의 입력에 대해 Ravinder에게 감사드립니다. 실제로 여기서도 혼란 스럽습니다. 't1.pk1이 null'이거나, 'not null'이거나, 전체 where 절을 제거하려고합니다. 결과는 여전히 'NULL'입니다. 실제로 여기에 where 절을 넣는 요점은 무엇입니까? 다른 사람들의 코드를 참조하고 있으므로 여기에 몇 가지 지침이 필요합니다. – redcasper

+0

@Ravinder, 주어진 이벤트 (ei2)에 대해 행 번호 또는 각 sub_event (pk1)에 대한 인덱스를 추가하려고했습니다. 원래 메시지를 업데이트했습니다. 어떻게해야합니까? – redcasper

답변

0

@Ravinder의 힌트와 함께, 나는 마지막으로 더러운 작업을 수행 할 SQL을 제안합니다.

SELECT ek2, 
    MAX(case when row_n =1 THEN e1 END) as et1, 
    MAX(case when row_n =2 THEN e1 END) as et2, 
    MAX(case when row_n =3 THEN e1 END) as et3, 
    MAX(case when row_n =4 THEN e1 END) as et4 
FROM (SELECT pk1, e1, ek2, t1, 
     (CASE ek2 
      WHEN @curType 
      THEN @curRow := @curRow + 1 
      ELSE @curRow := 1 AND @curType := ek2 END 
     ) + 1 AS row_n 
    FROM Table1 
    join (select @curRow :=0, @curType := '') r 
    -- where pk1 is NOT null 
    ORDER by ek2,t1,row_n) as rn 
GROUP by ek2; 

이 것은 정확히 그 결과 모든 주제를 통해 귀하의 의견과 관심에 대한

a0001, banner, search, search, (null) 
a0002, banner, search, (null), (null) 

감사를 제공합니다.

여기가 바로입니다. http://sqlfiddle.com/#!2/1fb10d/1/0 P. 나는 pk1이 Null 인 곳을 논평한다. 그것은 임의적이거나 추가하는 것이나 결과에 영향을 미치지 않을 것이다.

rc.

+0

15 et,이 경우 코드를 더 짧게/더 깔끔하게 만들려면 어떻게해야합니까? – redcasper

관련 문제