【问题标题】:Count Distinct Records between a repeating record in column using BigQuery SQL使用 BigQuery SQL 计算列中重复记录之间的不同记录
【发布时间】:2022-12-09 16:11:51
【问题描述】:

我在下面的表中有一列

| Column A | Column B |
| Active   | 202211210423 |
|   XYZ    | 202211210424 |
|   XYZ    | 202211210424 |
...

|   PQR    | 202211210426 |
| Active   | 202211210523 |
| abc      | 202211210525 |

Table_Input

如何计算 A 列中“活动”之间的不同记录?

输出可以像,COLUMN C 是“Active”之间的不同计数。

| Column A | Column B     | Column C |
| Active   | 202211210423 | x
|   XYZ    | 202211210424 | 24
|   XYZ    | 202211210424 | 24
...

|   PQR    | 202211210426 | 24 
| Active   | 202211210523 | 24
| abc      | 202211210525 | y 

Expected_output

我们可以使用分析函数来做到这一点吗?

我尝试使用 FIRST_VALUE 函数它没有用,因为它们都会第一次出现 Active。

输入字段 1

输出 2

【问题讨论】:

  • 数数在哪里ColBActive的值分别为0、3、1输出 2.他们的意思是什么 ?
  • 它是来自当前行的前一个不同时间戳的计数 = 活动。这 3 个计数是 2022120601310、2022120601325、2022120601342,其他计数相同。
  • 您的新输出示例没有意义。请检查您的第二个示例。请解释“计算 A 列中的不同记录”是什么意思。 ColA 列只有值“T100”,因此非重复计数始终为一,而不是第二个示例中的三。

标签: sql google-bigquery


【解决方案1】:

不确定我清楚地了解您的要求,但您可以考虑以下内容。

SELECT * EXCEPT(agg, part),
       (SELECT COUNT(DISTINCT x.timestamp) FROM t.agg x WHERE x.colB <> 'Active') Count,
  FROM (
    SELECT *, ARRAY_AGG(STRUCT(timestamp, colB)) OVER (PARTITION BY colA, part) agg FROM (
      SELECT *, COUNT(1) OVER w0 - COUNTIF(colB <> 'Active') OVER w1 AS part
        FROM sample_data
      WINDOW w0 AS (PARTITION BY colA ORDER BY timestamp ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),
             w1 AS (PARTITION BY colA ORDER BY timestamp ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)
    )
  ) t
 ORDER BY timestamp;

查询结果

【讨论】:

    【解决方案2】:

    首先我们在表tbl 中生成一些样本数据。

    对于非重复计数,组标识符很有用,创建为 row_group 。然后单独查看每个分区。

    with tbl as (select *, 1000+cast(rand()*5 as int64)+10*row_number() over () as colB from unnest(["Active","Y","X","Active","Y","Z","X","Active"])colA ),
    helper as (select *, countif(colA="Active") over (order by colB rows between  unbounded preceding and 1 preceding) as row_group from tbl)
    select *,
    -1+count(distinct colA) over (partition by row_group)
     from helper
    

    为了计算总数,这种方式更容易: 然后我们通过colB的顺序创建一个带有行号的helper表。必须为 unbounded precedingunbounded following 找到此行号的最小值和最大值。减法给出这些关键词之间的总量。

    with tbl as (select *, 1000+cast(rand()*5 as int64)+10*row_number() over () as colB from unnest(["Active","Y","X","Active","Y","Z","X","Active"])colA ),
    helper as (select *, row_number() over (order by colB) as row_id from tbl)
    select *,
    min(if(colA="Active",row_id,null)) over (order by colB rows between current row and unbounded following)-
    ifnull(max(if(colA="Active",row_id,null)) over (order by colB rows between unbounded preceding and 1 preceding),0)
     from helper
    

    【讨论】:

    • 它对我 Samuel 不起作用,因为它不完全是从最高到最低的减法,我需要在那些活跃的之间进行计数。 Col B 不一定有不断增加的数字,即 424,425...。它会像 424,426、430 等。在这种情况下,Max - Min 不会给出正确答案。
    • helper 表创建行号row_id,该行号增加 1。 col B 不需要有不断增加的数字。我的回答使用 Col B 的随机数来模仿这个。
    • 嗨塞缪尔,我又添加了一个专栏,您可以在其中了解我的表格的外观。请检查问题中的第三张和第四张图片。
    猜你喜欢
    • 2017-07-13
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 2014-06-11
    • 1970-01-01
    • 2014-01-04
    • 2021-06-19
    • 1970-01-01
    相关资源
    最近更新 更多