具有时间戳排序的MySQL pivot表查询

具有时间戳排序的MySQL pivot表查询,mysql,pivot,Mysql,Pivot,我有以下表格,pk1是主键且唯一,t1是事件的时间,e1是事件类型,ek2是事件键,因此对于同一ek2,可能会有多个事件 样本数据在这里 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, a0

我有以下表格,pk1是主键且唯一,t1是事件的时间,e1是事件类型,ek2是事件键,因此对于同一ek2,可能会有多个事件

样本数据在这里

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');
我期望的结果如下,在原始数据库中,每个事件最多有15个事件

event key, 1st event, 2nd event, 3rd event, ...
a0001, banner, search, search
a0002, banner, search
经过几个小时的反复试验,我提出了以下问题,它解释了前四个晚上的情况。如果没有bug,我会将其扩展到第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的最大时间戳。我提到,但结果是这样的

a0001, null, null, null, null               
a0002, null, null, null, null
我的代码有什么问题

更新1:感谢Ravinder的输入,我还想为给定事件ei2的每个sub_事件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。关于,我通过这个更新查询添加了行号

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;
结果是这样的

a0001, banner, banner, search, (null)
a0002, banner, (null), (null), (null)
它非常接近我想要的,但是还有一个额外的问题,您看到第二个事件是a0001的横幅,a0002的为空。正确的方法应该是搜索a0001,也应该搜索a0002。这里怎么了

如果我删除where t1.pk1 is NOT null子句

这仍然是不正确的

进一步的问题,如果事件的数量是一个变量,我们能把它变成一个动态的吗?就像

首先非常感谢您的关注

干杯


rc.

在@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)
感谢大家对这个主题的投入和关注

这是小提琴 另外,我要指出的是,其中pk1不是空的,因为它是任意的,添加它或不添加它都不会影响结果


rc.

问题必须位于“其中t1.pk1为空”。我认为应该是“不为空”。否则,子查询将始终返回'NULL'值。感谢Ravinder的输入,实际上我在这里也很困惑,我尝试了'where t1.pk1 is NULL','is NOT NULL',甚至删除了整个where子句。结果仍然是空的。在这里放where子句到底有什么意义?因为我引用了别人的人员代码,所以这里需要一些指导。@Ravinder,我想为给定事件ei2的每个子事件pk1添加一个行号或某种索引。我刚刚更新了原始消息。我应该怎么做?如果我有15个et,在这种情况下我如何使代码更短/更干净?
a0001,  banner, search, search, (null)  
a0002,  banner, search, (null), (null)