我们如何将PostgreSQL表的数据转换为热图数据?

时间:2018-12-05 19:10:40

标签: mysql sql postgresql

我的表包含user_iddatetime

user_id    date       time
129629  2018-11-01  01:18:50 PM
188747  2018-11-02  02:18:50 PM
261476  2018-11-03  06:18:50 PM
101866  2018-11-04  02:19:36 PM
156421  2018-11-05  06:23:01 PM
190261  2018-11-06  01:23:01 PM
247427  2018-11-07  05:23:01 PM
247579  2018-11-08  03:23:01 PM
170536  2018-11-09  01:23:42 PM
186961  2018-11-10  04:24:51 PM
118408  2018-11-11  01:18:50 PM
900006  2018-11-12  02:18:50 PM
900095  2018-11-13  01:18:50 PM
162458  2018-11-14  02:19:36 PM
100881  2018-11-15  06:23:01 PM
136095  2018-11-16  01:23:01 PM
100881  2018-11-17  05:23:01 PM
900058  2018-11-18  03:23:01 PM
134921  2018-11-19  02:18:50 PM
162873  2018-11-20  01:24:51 PM

我想通过以下特定数据创建访问者热图,如下面的示例所示:

           sun  mon tue wed thu fri sat
01:00:00 PM 1   0   3   0   1   2   0
02:00:00 PM 1   2   0   1   0   1   0
03:00:00 PM 1   0   0   0   1   0   0
04:00:00 PM 0   0   0   0   0   0   1
05:00:00 PM 0   0   0   1   0   0   1
06:00:00 PM 0   1   0   0   1   0   1

到目前为止,借助此查询,我只能获取时间范围之间的日期列表。

select date from user_visits where time >='01:00:00' and time <='01:59:59'

我无法理解如何格式化给定样本的数据。

2 个答案:

答案 0 :(得分:1)

经过过滤的聚合是最简单的方法:

ORCL12C =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = ORCL12C)
    )
  )

LISTENER_ORCL12C =
  (ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))


ORCL =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
    (CONNECT_DATA = 
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl)  
    ) 
  )

备注:

  • 我假定您正在使用数据类型SELECT date_trunc('hour', time) AS hour, count(*) FILTER (WHERE EXTRACT(dow FROM date) = 0) AS sun, count(*) FILTER (WHERE EXTRACT(dow FROM date) = 1) AS mon, count(*) FILTER (WHERE EXTRACT(dow FROM date) = 2) AS tue, count(*) FILTER (WHERE EXTRACT(dow FROM date) = 3) AS wed, count(*) FILTER (WHERE EXTRACT(dow FROM date) = 4) AS thu, count(*) FILTER (WHERE EXTRACT(dow FROM date) = 5) AS fri, count(*) FILTER (WHERE EXTRACT(dow FROM date) = 6) AS sat FROM user_visits GROUP BY hour ORDER BY hour; hour | sun | mon | tue | wed | thu | fri | sat ----------+-----+-----+-----+-----+-----+-----+----- 13:00:00 | 1 | 0 | 3 | 0 | 1 | 2 | 0 14:00:00 | 1 | 2 | 0 | 1 | 0 | 1 | 0 15:00:00 | 1 | 0 | 0 | 0 | 1 | 0 | 0 16:00:00 | 0 | 0 | 0 | 0 | 0 | 0 | 1 17:00:00 | 0 | 0 | 0 | 1 | 0 | 0 | 1 18:00:00 | 0 | 1 | 0 | 0 | 1 | 0 | 1 (6 rows) date

  • 最好存储一个time without time zone而不是两个字段。

  • 查询使用标准SQL,但我不知道MySQL是否支持所使用的所有功能。

答案 1 :(得分:1)

使用date/time functions

date_part('hour', time) -- gives time rounded to hour
extract(dow from date) -- returns day of week from date

查询:

select 
    date_part('hour', time) as hour, 
    sum((extract(dow from date) = 0)::int) as sun,
    sum((extract(dow from date) = 1)::int) as mon,
    sum((extract(dow from date) = 2)::int) as tue,
    sum((extract(dow from date) = 3)::int) as wed,
    sum((extract(dow from date) = 4)::int) as thu,
    sum((extract(dow from date) = 5)::int) as fri,
    sum((extract(dow from date) = 6)::int) as sat
from user_visits 
group by hour
order by hour

Test it in rextester.