使用Bigquery根据另一列min(date)选择一列的值

Sim*_*ton 2 google-bigquery

假设我有下表:

AccountID   Email              status_update       date (dd/mm/yyyy) 
123456      foo@gmail.com      state1              02/02/2016
123456      foo@gmail.com      state2              10/010/2018
456123      bar@gmail.com      state2              05/04/2017
789123      foobar@gmail.com   state2              22/04/2016
789123      foobar@gmail.com   state1              17/06/2018
456345      cool@gmail.com     state1              13/08/2017
456345      cool@gmail.com     state2              09/07/2015
456345      cool@gmail.com     state2              09/07/2014
Run Code Online (Sandbox Code Playgroud)

这是我想要的输出:

UniqueID    Email              Most_recent_status_Update  CountUniqueID                    
123456      foo@gmail.com      state2                     2
456123      bar@gmail.com      state2                     1    
789123      foobar@gmail.com   state1                     2              
456345      cool@gmail.com     state1                     3
Run Code Online (Sandbox Code Playgroud)

所以基本上我希望能够到group by Email,做一个unique(AccountID)和选择status_update设在MIN(date)

对我来说,困难的是要status_update基于进行选择MIN(date)。我希望能够做这样的事情:

Select status_update when date = min(date)

我正在考虑使用CASE公式以便具有以下内容:

Select CASE (WHEN date = min(date) Then status_update else null END

我总是以各种错误告终。我无法建立整个查询。

谢谢

Mik*_*ant 5

请参见下面的示例-有关BigQuery标准SQL

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 123456 accountID, 'foo@gmail.com' email, 'state1' status_update, '02/02/2016' dt UNION ALL
  SELECT 123456, 'foo@gmail.com', 'state2', '10/10/2018' UNION ALL
  SELECT 456123, 'bar@gmail.com', 'state2', '05/04/2017' UNION ALL
  SELECT 789123, 'foobar@gmail.com', 'state2', '22/04/2016' UNION ALL
  SELECT 789123, 'foobar@gmail.com', 'state1', '17/06/2018' UNION ALL
  SELECT 456345, 'cool@gmail.com', 'state1', '13/08/2017' UNION ALL
  SELECT 456345, 'cool@gmail.com', 'state2', '09/07/2015' UNION ALL
  SELECT 456345, 'cool@gmail.com', 'state2', '09/07/2014' 
)
SELECT 
  accountID, 
  email, 
  ARRAY_AGG(status_update ORDER BY PARSE_DATE('%d/%m/%Y', dt) DESC LIMIT 1)[OFFSET (0)] most_recent_status_update,
  COUNT(1) AS cnt
FROM `project.dataset.table`
GROUP BY accountID, email   
Run Code Online (Sandbox Code Playgroud)

结果为

Row accountID   email               most_recent_status_update   cnt  
1   456123      bar@gmail.com       state2                      1    
2   123456      foo@gmail.com       state2                      2    
3   789123      foobar@gmail.com    state1                      2    
4   456345      cool@gmail.com      state1                      3     
Run Code Online (Sandbox Code Playgroud)

对于您的实际用例,您应该使用如下所示的内容

#standardSQL
SELECT 
  accountID, 
  email, 
  ARRAY_AGG(status_update ORDER BY PARSE_DATE('%d/%m/%Y', dt) DESC LIMIT 1)[OFFSET (0)] most_recent_status_update,
  COUNT(1) AS cnt
FROM `project.dataset.table`
GROUP BY accountID, email    
Run Code Online (Sandbox Code Playgroud)

注意:本示例假定特定的架构/数据类型(基于您所讨论的示例)-因此,如果您的实际数据类型不同-您需要稍微调整一下内容:o)

  • 1)BQ旧版SQL甚至不支持数组功能2)BigQuery团队强烈建议使用BQ标准SQL 3)从技术上讲-两种方言几乎都可以完成-因此,如果您确实需要在旧版SQL中使用此功能,则可以发布新问题,有人(包括我自己)可能会回答:o) (2认同)