有没有办法从 min(date) 开始按 30 天的间隔对时间戳数据进行分组并将它们添加为列

Posted

技术标签:

【中文标题】有没有办法从 min(date) 开始按 30 天的间隔对时间戳数据进行分组并将它们添加为列【英文标题】:Is there a way to group timestamp data by 30 day intervals starting from the min(date) and add them as columns 【发布时间】:2019-05-29 17:04:56 【问题描述】:

我正在尝试使用时间戳的 min() 值作为起点,然后按 30 天的时间间隔对数据进行分组,以便将时间戳日期范围内的每个唯一值的出现次数作为列获取

我有两个表,我将它们连接在一起进行计数。表 1 (page_creation) 有 2 列标记为 link 和 dt_crtd。表 2(页面访问)还有 2 个标记为 url 和 date 的列。通过加入 table1.link = table2.pagevisits 来加入表。

加入后我得到一个类似这样的表:

+-------------------+------------------------+
| url               |     date               |
+-------------------+------------------------+
| www.google.com    | 2018-01-01 00:00:00'   |
| www.google.com    | 2018-01-02 00:00:00'   |
| www.google.com    | 2018-02-01 00:00:00'   |
| www.google.com    | 2018-02-05 00:00:00'   |
| www.google.com    | 2018-03-04 00:00:00'   |
| www.facebook.com  | 2014-01-05 00:00:00'   |
| www.facebook.com  | 2014-01-07 00:00:00'   |
| www.facebook.com  | 2014-04-02 00:00:00'   |
| www.facebook.com  | 2014-04-10 00:00:00'   |
| www.facebook.com  | 2014-04-11 00:00:00'   |
| www.facebook.com  | 2014-05-01 00:00:00'   |
| www.twitter.com   | 2016-02-01 00:00:00'   |
| www.twitter.com   | 2016-03-04 00:00:00'   |
+---------------------+----------------------+

我想要得到的是结果:

+-------------------+------------------------+------------+------------+-------------+
| url               | MIN_Date               | Interval 1  | Interval 2|  Interval 3 |
+-------------------+------------------------+-------------+-----------+-------------+
| www.google.com    | 2018-01-01 00:00:00'   |  2          |  2        |  1      
| www.facebook.com  | 2014-01-05 00:00:00'   |  2          |  0        |  1
| www.twitter.com   | 2016-02-01 00:00:00'   |  1          |  1        |  0    
+---------------------+----------------------+-------------+-----------+-------------+

所以 30 天的间隔从 min(date) 开始,如间隔 1 所示,每 30 天计算一次。

我看过其他问题,例如:

Group rows by 7 days interval starting from a certain date

mysql query to select min datetime grouped by 30 day intervals

但是它似乎没有回答我的具体问题。

我还研究了枢轴语法,但注意到它仅支持某些 DBMS。

任何帮助将不胜感激。

谢谢。

【问题讨论】:

您是否希望根据找到的 30 天间隔获得可变数量的列? 【参考方案1】:

如果我清楚地理解了您的问题,您希望在页面创建后 30 、 60 、 90 天的时间间隔内计算页面访问量。如果需要,请尝试以下 SQL 代码:-

select a11.url
,Sum(case when a12.date between a11.dt_crtd and a11.dt_crtd+30 then 1 else 0) Interval_1    
,Sum(case when a12.date between a11.dt_crtd+31 and a11.dt_crtd+60 then 1 else 0) Interval_2
,Sum(case when a12.date between a11.dt_crtd+61 and a11.dt_crtd+90 then 1 else 0) Interval_3 
from page_creation a11
join page_visits a12
on a11.link = a12.url
group by a11.url

【讨论】:

我稍后去办公室时会试试。 dt_crtd 是时间戳有关系吗?换句话说,在不需要将时间戳转换为 Char() 的情况下添加 +30 会起作用吗?还要回答您的问题,是的,您清楚地理解了我的问题!非常感谢。【参考方案2】:

如果您使用 BigQuery,我建议:

countif() 计算布尔值 timestamp_add() 为时间戳添加间隔

确切的界限有点​​模糊,但我会选择:

select pc.url,
       countif(pv.date >= pc.dt_crtd and
               pv.date < timestamp_add(pc.dt_crtd, interval 30 day
              ) as Interval_00_29,    
       countif(pv.date >= timestamp_add(pc.dt_crtd, interval 30 day) and
               pv.date < timestamp_add(pc.dt_crtd, interval 60 day
              ) as Interval_30_59,    
       countif(pv.date >= timestamp_add(pc.dt_crtd, interval 60 day) and
               pv.date < timestamp_add(pc.dt_crtd, interval 90 day
              ) as Interval_60_89
from page_creation pc join
     page_visits pv
     on pc.link = pv.url
group by pc.url

【讨论】:

【参考方案3】:

我阅读您的场景的方式,特别是基于After the join i get a table similar to ... 的示例,您有两个表需要UNION - 而不是JOIN

因此,根据阅读,下面的示例适用于 BigQuery 标准 SQL(project.dataset.page_creationproject.dataset.page_visits 只是为了模仿您的表 1 和表 2)

#standardSQL
WITH `project.dataset.page_creation` AS (
  SELECT 'www.google.com' link, TIMESTAMP '2018-01-01 00:00:00' dt_crtd UNION ALL
  SELECT 'www.facebook.com', '2014-01-05 00:00:00' UNION ALL
  SELECT 'www.twitter.com', '2016-02-01 00:00:00' 
), `project.dataset.page_visits` AS (
  SELECT 'www.google.com' url, TIMESTAMP '2018-01-02 00:00:00' dt UNION ALL
  SELECT 'www.google.com', '2018-02-01 00:00:00' UNION ALL
  SELECT 'www.google.com', '2018-02-05 00:00:00' UNION ALL
  SELECT 'www.google.com', '2018-03-04 00:00:00' UNION ALL
  SELECT 'www.facebook.com', '2014-01-07 00:00:00' UNION ALL
  SELECT 'www.facebook.com', '2014-04-02 00:00:00' UNION ALL
  SELECT 'www.facebook.com', '2014-04-10 00:00:00' UNION ALL
  SELECT 'www.facebook.com', '2014-04-11 00:00:00' UNION ALL
  SELECT 'www.facebook.com', '2014-05-01 00:00:00' UNION ALL
  SELECT 'www.twitter.com', '2016-03-04 00:00:00' 
), `After the join` AS (
  SELECT url, dt FROM `project.dataset.page_visits` UNION DISTINCT
  SELECT link, dt_crtd FROM `project.dataset.page_creation`
)
SELECT 
  url, min_date, 
  COUNTIF(dt BETWEEN min_date AND TIMESTAMP_ADD(min_date, INTERVAL 29 DAY)) Interval_1,
  COUNTIF(dt BETWEEN TIMESTAMP_ADD(min_date, INTERVAL 30 DAY) AND TIMESTAMP_ADD(min_date, INTERVAL 59 DAY)) Interval_2,
  COUNTIF(dt BETWEEN TIMESTAMP_ADD(min_date, INTERVAL 60 DAY) AND TIMESTAMP_ADD(min_date, INTERVAL 89 DAY)) Interval_3
FROM (
  SELECT url, dt, MIN(dt) OVER(PARTITION BY url ORDER BY dt) min_date
  FROM `After the join`
)
GROUP BY url, min_date

结果为

Row url                 min_date                    Interval_1  Interval_2  Interval_3   
1   www.facebook.com    2014-01-05 00:00:00 UTC     2           0           1    
2   www.google.com      2018-01-01 00:00:00 UTC     2           2           1    
3   www.twitter.com     2016-02-01 00:00:00 UTC     1           1           0    

【讨论】:

以上是关于有没有办法从 min(date) 开始按 30 天的间隔对时间戳数据进行分组并将它们添加为列的主要内容,如果未能解决你的问题,请参考以下文章

js判断时间格式不能超过30天

在WHERE子句中选择最小日期

Eloquent - 按“从日期”到“至今”分组,间隔为 1 天

mysqlsql时间查询

如何从现在开始7天分割日期

如何从 Java 中的 Date 对象中减去 X 天?