【问题标题】:How to get the count of distinct IDs each month which are different from the previous month?如何获取每个月与上个月不同的不同 ID 的计数?
【发布时间】:2020-02-21 05:05:28
【问题描述】:

我正在尝试计算每个月表中唯一 ID 的数量。但问题是每个月的 ID 计数应该只包括上个月不存在的 ID

我正在尝试编写一个可以在 google BigQuery 中使用的 SQL 查询,但到目前为止,我只知道如何获取每个月不同 ID 的计数。我无法弄清楚如何获得上个月不存在的 ID 的条件。

例如我有一张如下表 tbl1:

time_stamp | ID | col3 | col4
-------------------------------
2019-06-10 | 1  |  10  |  20
2019-06-10 | 2  |  11  |  21
2019-06-10 | 3  |  12  |  22
2019-07-10 | 2  |  11  |  21
2019-07-10 | 4  |  13  |  23
2019-08-10 | 4  |  13  |  23
2019-08-10 | 5  |  14  |  24
2019-09-10 | 5  |  14  |  24
2019-09-10 | 6  |  15  |  25

预期输出

time_stamp | count
--------------------
2019-06-10 |   3
2019-07-10 |   1
2019-08-10 |   1
2019-09-10 |   1

【问题讨论】:

标签: sql google-bigquery


【解决方案1】:

更新

我意识到 - 你要求 count of IDs for each month should only include IDs which were not present in the上个月 - 不是在前 几个月,而是 一个月

下面是解决方法

#standardSQL
SELECT month, COUNT(1) users
FROM (
  SELECT *, IFNULL(DATE_DIFF(month, LAG(month) OVER(PARTITION BY ID ORDER BY month), MONTH), 0) != 1 qualified
  FROM (
    SELECT DISTINCT DATE_TRUNC(time_stamp, MONTH) month, ID FROM `project.dataset.table` 
  )
)
WHERE qualified
GROUP BY month

您可以使用以下示例数据进行测试和使用

#standardSQL
WITH `project.dataset.table` AS (
  SELECT DATE '2019-06-10' time_stamp, 1 ID, 10 col3, 20 col4 UNION ALL
  SELECT '2019-06-10', 2, 11, 21 UNION ALL
  SELECT '2019-06-10', 3, 12, 22 UNION ALL
  SELECT '2019-06-11', 3, 12, 22 UNION ALL
  SELECT '2019-07-10', 2, 11, 21 UNION ALL
  SELECT '2019-07-10', 4, 13, 23 UNION ALL
  SELECT '2019-08-10', 1, 13, 23 UNION ALL
  SELECT '2019-08-10', 4, 13, 23 UNION ALL
  SELECT '2019-08-10', 5, 14, 24 UNION ALL
  SELECT '2019-09-10', 5, 14, 24 UNION ALL
  SELECT '2019-09-10', 6, 15, 25 
)
SELECT month, COUNT(1) users
FROM (
  SELECT *, IFNULL(DATE_DIFF(month, LAG(month) OVER(PARTITION BY ID ORDER BY month), MONTH), 0) != 1 qualified
  FROM (
    SELECT DISTINCT DATE_TRUNC(time_stamp, MONTH) month, ID FROM `project.dataset.table` 
  )
)
WHERE qualified
GROUP BY month
-- ORDER BY month

结果

Row month   users    
1   2019-06-01  3    
2   2019-07-01  1    
3   2019-08-01  2    
4   2019-09-01  1    

希望,这一次是你所要求的!

初步回答 以下是 BigQuery 标准 SQL 并返回前几个月未显示的用户数

#standardSQL
SELECT time_stamp, COUNT(1) `count`
FROM (
  SELECT *, COUNT(1) OVER(PARTITION BY ID ORDER BY time_stamp) = 1 first_entry
  FROM `project.dataset.table`
)
WHERE first_entry
GROUP BY time_stamp

如果应用于您问题的样本数据 - 输出是

Row time_stamp  count    
1   2019-06-10  3    
2   2019-07-10  1    
3   2019-08-10  1    
4   2019-09-10  1    

您可以使用下面的示例进行测试,玩它

#standardSQL
WITH `project.dataset.table` AS (
  SELECT DATE '2019-06-10' time_stamp, 1 ID, 10 col3, 20 col4 UNION ALL
  SELECT '2019-06-10', 2, 11, 21 UNION ALL
  SELECT '2019-06-10', 3, 12, 22 UNION ALL
  SELECT '2019-07-10', 2, 11, 21 UNION ALL
  SELECT '2019-07-10', 4, 13, 23 UNION ALL
  SELECT '2019-08-10', 4, 13, 23 UNION ALL
  SELECT '2019-08-10', 5, 14, 24 UNION ALL
  SELECT '2019-09-10', 5, 14, 24 UNION ALL
  SELECT '2019-09-10', 6, 15, 25 
)
SELECT time_stamp, COUNT(1) `count`
FROM (
  SELECT *, COUNT(1) OVER(PARTITION BY ID ORDER BY time_stamp) = 1 first_entry
  FROM `project.dataset.table`
)
WHERE first_entry
GROUP BY time_stamp
-- ORDER BY time_stamp

如果您需要按月与按日期分组(从您的问题中不清楚)

#standardSQL
WITH `project.dataset.table` AS (
  SELECT DATE '2019-06-10' time_stamp, 1 ID, 10 col3, 20 col4 UNION ALL
  SELECT '2019-06-11', 2, 11, 21 UNION ALL
  SELECT '2019-06-12', 3, 12, 22 UNION ALL
  SELECT '2019-07-10', 2, 11, 21 UNION ALL
  SELECT '2019-07-11', 4, 13, 23 UNION ALL
  SELECT '2019-08-10', 4, 13, 23 UNION ALL
  SELECT '2019-08-12', 5, 14, 24 UNION ALL
  SELECT '2019-09-10', 5, 14, 24 UNION ALL
  SELECT '2019-09-13', 6, 15, 25 
)
SELECT DATE_TRUNC(time_stamp, MONTH) month, COUNT(1) `count`
FROM (
  SELECT *, COUNT(1) OVER(PARTITION BY ID ORDER BY time_stamp) = 1 first_entry
  FROM `project.dataset.table`
)
WHERE first_entry
GROUP BY month
-- ORDER BY month

以上返回每月用户,不包括前几个月的用户

Row month   count    
1   2019-06-01  3    
2   2019-07-01  1    
3   2019-08-01  1    
4   2019-09-01  1    

【讨论】:

    【解决方案2】:

    您可以使用两个级别的聚合:

    select yyyymm, count(*)
    from (select id, date_trunc(min(time_stamp), month) as yyyymm
          from tbl1
          group by id
         ) t
    group by yyyymm
    order by yyyymm;
    

    【讨论】:

      猜你喜欢
      • 2020-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-27
      • 2021-01-08
      • 1970-01-01
      • 2021-02-18
      相关资源
      最近更新 更多