代码之家  ›  专栏  ›  技术社区  ›  DarkLeafyGreen

查询以查找在bigquery中创建的记录

  •  0
  • DarkLeafyGreen  · 技术社区  · 5 年前

    我在玩bigquery。给出以下输入:

    +---------------+---------+---------+--------+----------------------+
    |   customer    |  agent  |  value  |  city  |   timestamp          |
    +---------------+---------+---------+--------+----------------------+
    | 1             | 1       |  106    | LA     |  2019-02-12 03:05pm  |
    | 1             | 1       |  251    | LA     |  2019-02-12 03:06pm  |
    | 3             | 2       |  309    | NY     |  2019-02-12 06:41pm  |
    | 1             | 1       |  654    | LA     |  2019-02-12 05:12pm  |
    +---------------+---------+---------+--------+----------------------+
    

    我想找到由同一个代理一个接一个(比如说5分钟内)发出的交易。因此上表的输出应如下所示:

    +---------------+---------+---------+--------+----------------------+
    |   customer    |  agent  |  value  |  city  |   timestamp          |
    +---------------+---------+---------+--------+----------------------+
    | 1             | 1       |  106    | LA     |  2019-02-12 03:05pm  |
    | 1             | 1       |  251    | LA     |  2019-02-12 03:06pm  |
    +---------------+---------+---------+--------+----------------------+
    

    查询应该以某种方式按代理分组并找到这样的事务。然而,结果并不是真正的分组,正如您从输出中看到的那样。我的第一个想法是使用LEAD函数,但我不确定。你有什么想法吗?

    查询思路:

    • 按代理和时间戳说明排序
    • 从第一行开始,看下一行(使用铅?)
    • 如果是这样,这两行应该在输出中
    • 下一行继续

    当第2行和第3行也符合条件时,第2行将进入输出,这将导致重复行。我还不知道如何避免这种情况。

    0 回复  |  直到 5 年前
        1
  •  2
  •   Bobbylank    5 年前

    一定有一个更简单的方法,但这能达到你所追求的吗?

    CTE2 AS (
    SELECT customer, agent, value, city, timestamp,
      lead(timestamp,1) OVER (PARTITION BY agent ORDER BY timestamp) timestamp_lead,
      lead(customer,1) OVER (PARTITION BY agent ORDER BY timestamp) customer_lead,
      lead(value,1) OVER (PARTITION BY agent ORDER BY timestamp) value_lead,
      lead(city,1) OVER (PARTITION BY agent ORDER BY timestamp) city_lead,
      lag(timestamp,1) OVER (PARTITION BY agent ORDER BY timestamp) timestamp_lag
    FROM CTE
    )
    
    SELECT agent, 
      if(timestamp_diff(timestamp_lead,timestamp,MINUTE)<5, concat(cast(customer as string),', ',cast(customer_lead as string)),cast(customer as string)) customer, 
      if(timestamp_diff(timestamp_lead,timestamp,MINUTE)<5, concat(cast(value as string),', ',cast(value_lead as string)),cast(value as string)) value,
      if(timestamp_diff(timestamp_lead,timestamp,MINUTE)<5, concat(cast(city as string),', ',cast(city_lead as string)),cast(city as string)) cities,
      if(timestamp_diff(timestamp_lead,timestamp,MINUTE)<5, concat(cast(timestamp as string),', ',cast(timestamp_lead as string)),cast(timestamp as string)) timestamps
    FROM CTE2
    WHERE (timestamp_diff(timestamp_lead,timestamp,MINUTE)<5 OR NOT timestamp_diff(timestamp,timestamp_lag,MINUTE)<5)
    
        2
  •  0
  •   Mikhail Berlyant    5 年前

    #standardSQL
    SELECT * FROM (
      SELECT *, 
        IF(TIMESTAMP_DIFF(LEAD(ts) OVER(PARTITION BY agent ORDER BY ts), ts, MINUTE) < 5, 
          LEAD(STRUCT(customer AS next_customer, value AS next_value)) OVER(PARTITION BY agent ORDER BY ts), 
        NULL).* 
      FROM `project.dataset.yourtable`
    )
    WHERE NOT next_customer IS NULL
    

    您可以使用问题中的示例数据测试和使用上面的示例,如下例所示

    #standardSQL
    WITH `project.dataset.table` AS (
      SELECT 1 customer, 1 agent, 106 value,'LA' city, '2019-02-12 03:05pm' ts UNION ALL
      SELECT 1, 1, 251,'LA', '2019-02-12 03:06pm' UNION ALL
      SELECT 3, 2, 309,'NY', '2019-02-12 06:41pm' UNION ALL
      SELECT 1, 1, 654,'LA', '2019-02-12 05:12pm' 
    ), temp AS (
      SELECT customer, agent, value, city, PARSE_TIMESTAMP('%Y-%m-%d %I:%M%p', ts) ts 
      FROM `project.dataset.table`
    )
    SELECT * FROM (
      SELECT *, 
        IF(TIMESTAMP_DIFF(LEAD(ts) OVER(PARTITION BY agent ORDER BY ts), ts, MINUTE) < 5, 
          LEAD(STRUCT(customer AS next_customer, value AS next_value)) OVER(PARTITION BY agent ORDER BY ts), 
        NULL).* 
      FROM temp
    )
    WHERE NOT next_customer IS NULL
    -- ORDER BY ts
    

    Row customer    agent   value   city    ts                      next_customer   next_value   
    1   1           1       106     LA      2019-02-12 15:05:00 UTC 1               251