Sql 滑动数值,使其大于左列

Sql 滑动数值,使其大于左列,sql,google-bigquery,Sql,Google Bigquery,我有一个这样的结果表 id | p1 | p2 | p3 | p4 a | 1 | 1 | 2 | 5 b | 2 | 3 | 5 | 5 c | 2 | 2 | 2 | 2 是否有任何方法可以将相同值的列向上滑动,直到行中出现具有相同值的列 预期结果 id | p1 | p2 | p3 | p4 a | 1 | 2 | 3 | 5 b | 2 | 3 | 5 | 6 c | 2 | 3 | 4 | 5 背后的逻辑(a): p1=p2->向上滑

我有一个这样的结果表

id | p1 | p2 | p3 | p4
a  | 1  |  1 | 2  | 5
b  | 2  |  3 | 5  | 5
c  | 2  |  2 | 2  | 2
是否有任何方法可以将相同值的列向上滑动,直到行中出现具有相同值的列

预期结果

id | p1 | p2 | p3 | p4
a  | 1  | 2  | 3  | 5
b  | 2  | 3  | 5  | 6
c  | 2  | 3  | 4  | 5
背后的逻辑(a):

  • p1=p2->向上滑动p2至2[p1=1,p2=2]
  • 新建p2=p3->向上滑动p3至3[p1=1,p2=2,p3=3]
  • 完成,因为行中的所有值都不相同

  • 我将此问题解释为增加
    p
    列的值,直到它们都在一行中增加一个distinct

    我认为这是一个固有的迭代问题。这表明了一种蛮力方法——分别计算每个新的
    p

    事实上,这并不是那么糟糕:

    with t as (
          select 'a' as id, 1 as p1, 1 as p2, 2 as p3, 5 as p4 union all
          select 'b', 2, 3, 5, 5 union all
          select 'd', 2, 2, 3, 3 union all
          select 'c', 2, 2, 2, 2
         )
    select t.*,
           (case when p4 <= new_p3 then new_p3 + 1 else p4 end) as new_p4
    from (select t.*,
                 (case when p3 <= new_p2 then new_p2 + 1 else p3 end) as new_p3
          from (select t.*, p1 as new_p1,
                       (case when p2 <= p1 then p1 + 1 else p2 end) as new_p2,
                from t
               ) t
         ) t;
    
    带t作为(
    选择“a”作为id,1作为p1,1作为p2,2作为p3,5作为p4 union all
    选择“b”、2、3、5、5联合所有
    选择“d”、2、2、3、3联合所有
    选择“c”、2、2、2、2
    )
    选择t.*,
    
    (以下p4用于BigQuery标准SQL并使用JS UDF时的情况)

    #standardSQL
    CREATE TEMP FUNCTION slider(t STRUCT<p1 INT64, p2 INT64, p3 INT64, p4 INT64>)
    RETURNS STRUCT<p1 INT64, p2 INT64, p3 INT64, p4 INT64>
    LANGUAGE js AS """
      r = []; for (v in t) r.push(t[v]);
      prev = r[0]; for (i = 1; i < r.length; i++) {
        if(r[i] <= prev) r[i] = ++prev;
        prev = r[i];
      }
      i = 0; for (v in t) t[v] = r[i++];  
      return t;
    """;
    SELECT id, slider(STRUCT(p1, p2, p3, p4)).*
    FROM `project.dataset.table`   
    

    p4是如何计算的?@Fahmi它是相同的,但在我带来的情况下(id:a)是停止的,直到调整p3,因为所有的值都不一样了。p1=1,p2=2,p3=3,p4=5。
    #standardSQL
    CREATE TEMP FUNCTION slider(t STRUCT<p1 INT64, p2 INT64, p3 INT64, p4 INT64>)
    RETURNS STRUCT<p1 INT64, p2 INT64, p3 INT64, p4 INT64>
    LANGUAGE js AS """
      r = []; for (v in t) r.push(t[v]);
      prev = r[0]; for (i = 1; i < r.length; i++) {
        if(r[i] <= prev) r[i] = ++prev;
        prev = r[i];
      }
      i = 0; for (v in t) t[v] = r[i++];  
      return t;
    """;
    WITH `project.dataset.table` AS (
      SELECT 'a' AS id, 1 AS p1, 1 AS p2, 2 AS p3, 5 AS p4 UNION ALL
      SELECT 'b', 2, 3, 5, 5 UNION ALL
      SELECT 'c', 2, 2, 2, 2 UNION ALL
      SELECT 'd', 2, 2, 3, 3 
    )
    SELECT id, slider(STRUCT(p1, p2, p3, p4)).*
    FROM `project.dataset.table`     
    
    Row id  p1  p2  p3  p4   
    1   a   1   2   3   5    
    2   b   2   3   5   6    
    3   c   2   3   4   5    
    4   d   2   3   4   5