【问题标题】:Finding the overall data from specific date using bigquery使用 bigquery 查找特定日期的整体数据
【发布时间】:2020-11-02 06:29:07
【问题描述】:

我正在使用 bigquery 创建一个查询,该查询将计算每个 ID 的特定日期起 5 天内的数据总数。到目前为止,我设法获得了结果,其中结果返回了每天(第 1 天到第 5 天)的数据,这意味着结果中有 5 个日期。但是,我想要的实际上是只返回 1 个日期,这是最后一个日期,所以它就像 1 个日期,显示每个 ID 从该特定日期起过去 5 天的整体数据。

样本数据:

示例代码:

  SELECT
   ID,
   Date,
    SUM(CASE WHEN Language = 'EN' THEN 1 ELSE 0 END) AS lang_EN,
    SUM(CASE WHEN Language = 'SN' THEN 1 ELSE 0 END) AS lang_SN,
     FROM (
      SELECT 
      DATE(Timestamp) as Date ,
       ID, 
      CASE 
     WHEN Language in ('EN', 'English') THEN 'EN' 
     WHEN Language in ('MY', 'Malay')  THEN 'MY' ELSE Language 
     END AS Language,  
           FROM t
           WHERE Smooch_User_ID IS NOT NULL AND DATE(Timestamp) between '2020-01-01' and '2020-01-31'
           GROUP BY   ID, Language, DATE(Timestamp) 
         )
          GROUP BY  ID,Date

样本输出:

到目前为止,查询返回从第 1 天到第 5 天的每个日期的数据。如何使它返回从第 1 天到第 5 天的整体数据,并仅返回第 5 天的日期列日期,如下所示(假设第 1 天是 2020-01-01,第 5 天是 2020-01-05)。

【问题讨论】:

  • 你能分享你想要达到的期望输出的样本吗?
  • 您应该展示您的初始输入数据以及所需的输出。你现在的问题在我看来是一个中间数据,无助于理解你的情况。见How to create a Minimal, Reproducible Example

标签: sql google-bigquery timestamp


【解决方案1】:

如果您使用脚本,我认为一种方法可能是声明变量,以便您可以在间隔中根据 end_date 提取/标记输出。例如。

    declare end_dt date default "2020-07-05"; -- this can be used as placeholder and replaced at run-time based on execution
    declare start_dt date default DATE_SUB(end_dt, INTERVAL 5 DAY);
    
    select 
      end_dt as ts_date, 
      id, 
      sum(CASE WHEN lang = 'EN' THEN 1 ELSE 0 END) AS lang_EN, 
      sum(CASE WHEN lang = 'SN' THEN 1 ELSE 0 END) AS lang_SN 
    from(
      -- sample data
      select cast("2020-07-01 01:01:25.550 UTC" as timestamp) as ts, "A" as id, "EN" as lang
      union all
      select cast("2020-07-01 01:01:25.550 UTC" as timestamp) as ts, "A" as id, "EN" as lang
      union all
      select cast("2020-07-01 01:01:25.550 UTC" as timestamp) as ts, "A" as id, "SN" as lang
      union all
      select cast("2020-07-02 01:01:25.550 UTC" as timestamp) as ts, "B" as id, "EN" as lang
      union all
      select cast("2020-07-02 01:01:25.550 UTC" as timestamp) as ts, "B" as id, "EN" as lang
      union all
      select cast("2020-07-02 01:01:25.550 UTC" as timestamp) as ts, "B" as id, "SN" as lang
      union all
      select cast("2020-07-02 01:01:25.550 UTC" as timestamp) as ts, "B" as id, "SN" as lang
      union all
      select cast("2020-07-03 01:01:25.550 UTC" as timestamp) as ts, "C" as id, "SN" as lang
      union all
      select cast("2020-07-03 01:01:25.550 UTC" as timestamp) as ts, "C" as id, "EN" as lang
      union all
      select cast("2020-07-03 01:01:25.550 UTC" as timestamp) as ts, "D" as id, "SN" as lang
      union all
      select cast("2020-07-04 01:01:25.550 UTC" as timestamp) as ts, "D" as id, "EN" as lang
    ) where date(ts) between start_dt and end_dt
    group by 1,2

然后输出:

Row     ts_date     id  lang_EN     lang_SN      
1       2020-07-05  A   2           1    
2       2020-07-05  B   2           2    
3       2020-07-05  C   1           1    
4       2020-07-05  D   1           1

【讨论】:

    【解决方案2】:

    您的查询比必要的要复杂得多。如果您使用COUNT(DISTINCT),则根本不需要子查询:

    SELECT ID, 
           COUNT(DISTINCT Language in ('EN', 'English') THEN DATE(timestamp) END) AS lang_EN,
           COUNT(DISTINCT Language in ('MY', 'Malay') THEN DATE(timestamp) END) AS lang_SN
    FROM t
    WHERE Smooch_User_ID IS NOT NULL AND
          DATE(Timestamp) <= DATE('2020-01-31') AND
          DATE(Timestamp) >= DATE_ADD(DATE('2020-01-31'), INTERVAL 5 DAY)
    GROUP BY ID;
    

    我认为这也捕获了您尝试实现的日期逻辑。

    【讨论】:

      猜你喜欢
      • 2022-07-04
      • 1970-01-01
      • 2014-05-01
      • 1970-01-01
      • 2022-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多