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):
我将此问题解释为增加
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