【问题标题】:Discard rows with non-consecutive numbers in Google BigQuery Standard SQL丢弃 Google BigQuery 标准 SQL 中数字不连续的行
【发布时间】:2018-02-19 12:22:18
【问题描述】:

我的数据集的字段包含重复的数字序列(为简洁起见,1 - 5),以及一些数字乱序的行:

1
2
3
5 -- out of sequence, need to discard
4
5
1 -- sequence starts over
2
3
4
...

如何丢弃乱序的行? 谢谢!

更新:还有其他列来指定排序。

UPDATE2:用于测试的数据集:

WITH t AS (
  SELECT * FROM
  UNNEST([
    STRUCT(1 AS id, 1 AS n),
    (2, 2),
    (3, 3),
    (4, 5),
    (5, 4),
    (6, 5),
    (7, 1),
    (8, 2),
    (9, 3),
    (10, 4)
  ])
)

UPDATE3:可能有许多数字乱序(从相同的 1 - 5 范围内)。序列总是从 1 开始,所有数字都存在,除了最后一轮,它可能是不完整的(更早结束,参见测试集)。乱序的数字就像是需要去除的“噪音”。

【问题讨论】:

  • SQL 表代表 无序 集。哪一列用于确定排序?
  • 提供的示例非常简化,不存在通用案例(至少对我而言)。你能澄清排除的逻辑(只是一个乱序行,或者它可以是很多等等)和生存行的逻辑(它们应该代表整个集合 1-5 还是可以是部分的?等等 - 例如如果序列是 1,2,3,5,3,4,1,2,3,4 - 如果没有这些类型的详细信息,幸存的数字将是 1,2,3,3,4,1,2,3,4?在这里回答只是向空中射击:o)
  • @MikhailBerlyant 感谢您的评论,请参阅 update3,您的序列的答案是 1,2,3,4(所有其他都被丢弃,因为它应该在开始新一轮之前完成整轮,除了最后一轮)

标签: sql google-bigquery


【解决方案1】:

让我假设您有另一列来指定排序。如果不是,则问题没有明确定义。

如果是这样,你可以使用lag():

select t.*
from (select t.*, lag(col) over (order by row) as prev_col
      from t
     ) t
where (prev_col is null) or 
      (prev_col = col - 1) or
      (prev_col = 5 and col = 1);

? 用于指定排序的列。

【讨论】:

  • @AfanasiiKurakin 。 . .这似乎令人怀疑。您是否使用了正确的order by 列?
  • 你的答案给出 1,2,3,5,1,2,3,4 结果,应该是 1,2,3,4,5,1,2,3,4 - I' m 使用“其他列”的顺序
【解决方案2】:

以下是 BigQuery 标准 SQL 和使用 JS UDF
Tt 返回所有找到的以1 开头并带有以下连续数字的序列

#standardSQL
CREATE TEMPORARY FUNCTION extract_sequence(arr ARRAY<STRUCT<id INT64, n INT64>>) 
RETURNS ARRAY<STRUCT<id INT64, n INT64>>
LANGUAGE js AS """
  target = [1,2,3,4,5];
  var result = [];
  j = 0;
  for (i = 0; i < arr.length; i++) { 
    if (arr[i].n == target[j]) {
      x = [];
      x.id = arr[i].id;
      x.n = arr[i].n;
      result.push(x);
      j++
    } 
  }
  return result;
""";
WITH t AS (
  SELECT * 
  FROM UNNEST([
    STRUCT(1 AS id, 1 AS n), (2, 2), (3, 3), (4, 5), (5, 4), (6, 5), (7, 1), (8, 2), (9, 3), (10, 4)
  ])
)
SELECT elem.id, elem.n, grp
FROM (
  SELECT grp, extract_sequence(ARRAY_AGG(STRUCT(id, n) ORDER BY id)) arr
  FROM (
    SELECT id, n, COUNTIF(n = 1) OVER(ORDER BY id) grp
    FROM t
  )
  GROUP BY grp
), UNNEST(arr) elem
ORDER BY id  

结果符合预期:

Row id  n   grp  
1   1   1   1    
2   2   2   1    
3   3   3   1    
4   5   4   1    
5   6   5   1    
6   7   1   2    
7   8   2   2    
8   9   3   2    
9   10  4   2      

希望你能适应你的具体情况

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多