【问题标题】:BigQuery all time uniqueness by rowsBigQuery 的所有时间唯一性(按行)
【发布时间】:2021-11-18 19:30:40
【问题描述】:

我有一个与上周非常相似的问题:Get all time unique values in BigQuery

我有一个这样的数据库:

ID Day Value
1 2021-09-01 a
2 2021-09-01 b
3 2021-09-01 c
4 2021-09-02 d
5 2021-09-02 a
6 2021-09-02 a
7 2021-09-02 e
8 2021-09-03 c
9 2021-09-03 f
10 2021-09-03 a

我想计算我每天和所有时间有多少不同的行,但所有时间的唯一性应该只计算之前的日期(如果用户是新用户,我想计算其背后的业务逻辑) .与之前的问题不同,我想留下行,但我想按行查看唯一性(作为新列)。这与我们作为新用户或老用户在 Google Analytics(分析)上所拥有的几乎相同。因此,如果用户在 2021 年 9 月 2 日访问该站点并在 2021 年 9 月 3 日访问该站点,首先我希望看到新用户,但在 2021 年 9 月 3 日我希望看到返回用户。 所以我想看看这个输出

ID Day Value Type
1 2021-09-01 a New
2 2021-09-01 b New
3 2021-09-01 c New
4 2021-09-02 d New
5 2021-09-02 a Returning
6 2021-09-02 a Returning
7 2021-09-02 e Returning
8 2021-09-03 c New
9 2021-09-03 f New
10 2021-09-03 a Returning

如果我只检查一天我可以做到,但如果我在整个数据库上检查这些,我就不能这样做,因为检查前的日期。

【问题讨论】:

    标签: google-bigquery unique


    【解决方案1】:

    看来您想使用doc 中详述的分析功能

    使用OVERPARTITION BY 的分析功能,您可以通过值对数据进行分区,然后使用ORDER BY 按日期对其进行排序。现在检查它是否是该分区中的第一行并相应地分配类型。

    这个查询应该得到你想要的;

    WITH data as(
        SELECT "2021-09-01" day,"a" value
        UNION ALL ( SELECT "2021-09-01", "b" )
        UNION ALL ( SELECT "2021-09-01", "c" )
        UNION ALL ( SELECT "2021-09-02", "d" )
        UNION ALL ( SELECT "2021-09-02", "a" )
        UNION ALL ( SELECT "2021-09-02", "a" )
        UNION ALL ( SELECT "2021-09-02", "e" )
        UNION ALL ( SELECT "2021-09-03", "c" )
        UNION ALL ( SELECT "2021-09-03", "f" )
        UNION ALL ( SELECT "2021-09-03", "a" )
        )
        
        SELECT day, value,
          IF(ROW_NUMBER() OVER (PARTITION BY value ORDER BY day) = 1, 'New','Returning') as type
        
        FROM data
    
    

    结果

    Row day value type
    1 2021-09-01 a New
    2 2021-09-02 a Returning
    3 2021-09-02 a Returning
    4 2021-09-03 a Returning
    5 2021-09-01 b New
    6 2021-09-01 c New
    7 2021-09-03 c Returning
    8 2021-09-02 d New
    9 2021-09-02 e New
    10 2021-09-03 f New

    修改了附加要求

    要将具有相同日期的所有分组 values 作为第一个事件提供 New 类型,您可以使用另一个分析函数 FIRST_VALUE 并结合当前日期值。

    WITH data as
    (SELECT "2021-09-01" day,"a" value
    UNION ALL ( SELECT "2021-09-01","b")
    UNION ALL ( SELECT "2021-09-01","c")
    UNION ALL ( SELECT "2021-09-02","d")
    UNION ALL ( SELECT "2021-09-02","a")
    UNION ALL ( SELECT "2021-09-01","a")
    UNION ALL ( SELECT "2021-09-02","a")
    UNION ALL ( SELECT "2021-09-02","e")
    UNION ALL ( SELECT "2021-09-03","c")
    UNION ALL ( SELECT "2021-09-03","f")
    UNION ALL ( SELECT"2021-09-03","a"))
    
    SELECT *,
    IF(ROW_NUMBER() OVER (PARTITION BY value ORDER BY day) = 1 OR FIRST_VALUE(day) OVER (PARTITION BY value ORDER BY day) = day, 'New','Returning')  as type
    FROM data
    

    结果

    Row day value type
    1 2021-09-01 a New
    2 2021-09-01 a New
    3 2021-09-02 a Returning
    4 2021-09-02 a Returning
    5 2021-09-03 a Returning
    6 2021-09-01 b New
    7 2021-09-01 c New
    8 2021-09-03 c Returning
    9 2021-09-02 d New
    10 2021-09-02 e New
    11 2021-09-03 f New

    【讨论】:

    • 哇,太好了,谢谢!还有一件小事,如果一天内的值相同,例如“2021-09-01”,则每个值都应该是“新”。有什么优雅的解决方案吗? (我有一个加入分组结果的解决方案,但也许有更好的方法)
    • 我在回答中添加了另一部分,以回答您的进一步要求。这有帮助吗?
    • 哇,太棒了,它有效!非常感谢您的帮助,我今天学到了新东西!
    【解决方案2】:

    考虑下面的方法

    select *, if(0 = count(*) over prev_days, 'New', 'Returning') as type
    from your_table
    window prev_days as (
      partition by value order by unix_date(date(day)) 
      range between unbounded preceding and 1 preceding 
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-03
      • 1970-01-01
      • 2014-09-04
      • 2014-03-23
      • 2018-10-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多