SQL:计算每个页面花费的时间

时间:2016-01-28 10:55:00

标签: mysql sql

我有两张桌子:

Pages:

id  |       page |           date    |           visit_id
----     ----------      ---------             ------------
1         1           2015-05-07 13:53:50           1 
2         2           2015-05-07 13:53:54           1
3         3           2015-05-07 13:54:10           1
4         4           2015-05-07 13:54:49           1
5         1           2015-05-07 14:54:15           2 
6         3           2015-05-07 14:54:30           2
7         4           2015-05-07 14:54:37           2

Visits:

 id  |    end_date               
----     ---------                
 1       2015-05-07 13:54:55
 2       2015-05-07 14:54:50

我想获得每个页面的平均花费时间,因此在运行查询后,最终结果应如下所示:

page    count(seconds)
 1           9.5 
 2            16   
 3            23
 4            9.5

用户访问过的最后一页是使用访问表中的end_date计算的。

这个查询的外观如何?

编辑: 计算示例:

page 1 avg seeconds = (2015-05-07 13:53:54 - 2015-05-07 13:53:50 + 2015-05-07 14:54:30 - 2015-05-07 14:54:15) /2

last page avg = (2015-05-07 13:54:55 - 2015-05-07 13:54:49 + 2015-05-07 14:54:50 - 2015-05-07 14:54:37) / 2

1 个答案:

答案 0 :(得分:1)

考虑以下数据集:

DROP TABLE IF EXISTS pages;

CREATE TABLE pages
(id  INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,page INT NOT NULL
,date DATETIME NOT NULL
,visit_id INT NOT NULL
);

INSERT INTO pages VALUES
(1,1,'2015-05-07 13:53:50',1), 
(2,2,'2015-05-07 13:53:54',1), 
(3,3,'2015-05-07 13:54:10',1), 
(4,4,'2015-05-07 13:54:49',1), 
(5,1,'2015-05-07 14:54:15',2), 
(6,3,'2015-05-07 14:54:30',2), 
(7,4,'2015-05-07 14:54:37',2);

DROP TABLE IF EXISTS visits;

CREATE TABLE visits
(id INT NOT NULL 
,end_date DATETIME NOT NULL
);

INSERT INTO visits VALUES
(1,'2015-05-07 13:54:55'),
(2,'2015-05-07 14:54:50');

中间结果可能如下所示:

SELECT p.*
     , TIME_TO_SEC(TIMEDIFF(COALESCE(MIN(x.date),v.end_date),p.date)) n 
  FROM pages p 
  LEFT 
  JOIN pages x 
    ON x.visit_id = p.visit_id 
   AND x.date > p.date 
  JOIN visits v 
    ON v.id = p.visit_id 
 GROUP 
    BY p.id;
+----+------+---------------------+----------+------+
| id | page | date                | visit_id | n    |
+----+------+---------------------+----------+------+
|  1 |    1 | 2015-05-07 13:53:50 |        1 |    4 |
|  2 |    2 | 2015-05-07 13:53:54 |        1 |   16 |
|  3 |    3 | 2015-05-07 13:54:10 |        1 |   39 |
|  4 |    4 | 2015-05-07 13:54:49 |        1 |    6 |
|  5 |    1 | 2015-05-07 14:54:15 |        2 |   15 |
|  6 |    3 | 2015-05-07 14:54:30 |        2 |    7 |
|  7 |    4 | 2015-05-07 14:54:37 |        2 |   13 |
+----+------+---------------------+----------+------+

...因此,完整的查询可能看起来像这样...

SELECT page,AVG(n)
  FROM 
     ( SELECT p.*
            , TIME_TO_SEC(TIMEDIFF(COALESCE(MIN(x.date),v.end_date),p.date)) n 
         FROM pages p 
         LEFT 
         JOIN pages x 
           ON x.visit_id = p.visit_id 
          AND x.date > p.date 
         JOIN visits v 
           ON v.id = p.visit_id 
        GROUP 
           BY p.id
     ) a
 GROUP
    BY page;
+------+---------+
| page | AVG(n)  |
+------+---------+
|    1 |  9.5000 |
|    2 | 16.0000 |
|    3 | 23.0000 |
|    4 |  9.5000 |
+------+---------+