【问题标题】:Fill with zeros in a frequency of dates group by month and year in big query在大查询中按月和年分组的日期频率中填充零
【发布时间】:2019-02-14 14:43:13
【问题描述】:

我有一张表,上面有hiredate (Date)、First Name (String) 和 Sur Name (string),如下所示:

hireDate    First Name      Surname
13-oct-14   Cintia Roxana   Padilla Julca
28-oct-14   Conor           McAteer
28-oct-14   Paolo           Mesia Macher
28-oct-14   William Anthony Whelan
15-nov-14   Peter Michael   Coates
13-feb-15   Natalie         Conche
15-mar-15   Beatriz         Vargas Huanca
01-may-15   Walter          Calle Chenccnes
04-may-15   Sarah Louise    Price

我在另一列中查看了hire_dates(DATE) 的频率和累积频率,如下所示:

Row hireDate    Count       Cumulative
1   13/10/2014  1           1
2   28/10/2014  3           4
3   15/11/2014  1           5
4   13/02/2015  1           6
5   15/03/2015  1           7
6   09/04/2015  1           8
7   15/04/2015  1           9
8   01/05/2015  1           10

查询是这样的:

WITH
Data AS (
 SELECT
 hireDate,
 COUNT(1) AS Count
 FROM
 `human-resources-221122.human_resources.employees_view`
 WHERE
 status <> "cancelled"
 GROUP BY
 1 )

SELECT
hireDate,
Count,
SUM(Count) OVER (ORDER BY hireDate ASC ROWS BETWEEN UNBOUNDED PRECEDING 
AND CURRENT ROW) AS Cumulative
FROM
Data
ORDER BY
hireDate ASC

但我需要在那些没有计数的地方按月份和年份查看数字,例如:

Hire_Month  Hire_Year   Count   Cumulative
October     2014        4       4
November    2014        1       5
December    2014        0       5
January     2015        0       5
February    2015        1       6
March       2015        1       7
April       2015        2       9
May         2015        1       10

提前致谢。

【问题讨论】:

  • 你试过EXTRACT()或FORMAT_DATE()吗?
  • where??,在子查询中??
  • 它有效,但在那些没有计数的月份我需要零
  • 如果没有日期,则没有可分组的内容。这里的策略是首先创建一个 date_array 并在分组之前将您的查询加入它。 GENERATE_DATE_ARRAY() 在这里提供帮助。
  • 我从来没有使用过这种功能,你能告诉我我应该怎么做吗?

标签: sql google-bigquery fill cumulative-frequency


【解决方案1】:

注意使用GENERATE_DATE_ARRAY 和RIGHT JOIN 以获得所需的结果:

WITH data AS (
  SELECT * 
  FROM UNNEST ([
    STRUCT(DATE("2014-12-03") AS d, 4 AS a)
    , STRUCT("2015-01-05", 7)
    , STRUCT("2015-03-05", 1)
  ])
), all_months AS (
   SELECT month
   FROM UNNEST(GENERATE_DATE_ARRAY(
     (SELECT DATE_TRUNC(MIN(d), MONTH) FROM data)
     , (SELECT MAX(d) FROM data)
     , INTERVAL 1 MONTH)
   ) AS month
)


SELECT month, IFNULL(SUM(a),0) a, SUM(SUM(a)) OVER(ORDER BY month) a_cum
FROM data 
RIGHT JOIN all_months
ON DATE_TRUNC(d, MONTH)=month
GROUP BY month
ORDER BY month

现在,如果我们只是在计数,您可以使用 LEFT/RIGHT JOIN 将在空月份有空值这一事实。这就是查询如何适应任意表(此处为维基百科):

WITH data AS (
  SELECT *, DATE(datehour) d
  FROM `fh-bigquery.wikipedia_v3.pageviews_2018` 
  WHERE wiki='pt'
    AND (datehour BETWEEN '2018-09-30' AND '2018-09-30'
      OR datehour BETWEEN '2018-12-01' AND '2018-12-02'
    )
    AND title LIKE 'Calif%'
), all_months AS (
   SELECT month
   FROM UNNEST(GENERATE_DATE_ARRAY(
     (SELECT DATE_TRUNC(MIN(d), MONTH) FROM data)
     , (SELECT MAX(d) FROM data)
     , INTERVAL 1 MONTH)
   ) AS month
)


SELECT month, COUNT(d) c, SUM(COUNT(d)) OVER(ORDER BY month) a_cum
FROM data 
RIGHT JOIN all_months
ON DATE_TRUNC(d, MONTH)=month
GROUP BY month
ORDER BY month

【讨论】:

  • 很有趣,但是我从表中有 1000 行雇用日期,我不知道我是否可以将此表添加到查询中 -
  • 添加表格?你只需要GENERATE_DATE_ARRAY 和RIGHT JOIN
  • 在您的示例中,您展示了 3 个示例雇用日期,您使用 STRUCT(DATE("2014-12-03") AS d, 4 AS a) 作为您的第一个输入日期,但在我的表中,我没有 3 个,我有 1000 个雇用日期,我的问题是:我是否必须像您的示例一样逐个构造???,或者有一种方法可以从列名构造??跨度>
  • 我在查询中这样做了,因为我没有你的桌子。我有你的桌子吗,我会用那个。
  • 我用开头的表格更新问题,请查收。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-03
  • 1970-01-01
相关资源
最近更新 更多