Bigquery 中的表在从 1 到 100 的队列中具有 100 个或更多从 0.5 到 6 的数字,增量为 0.5。 您需要依次创建数字组。每组的数字之和为12。 图中是一个表格示例,第 1 组应由数字 1、2、3、6 组成,加起来为 12。缺少的数字 4、5 应进入下一组 我将不胜感激任何提示和想法。
我尝试先将它们分组以获得小于或等于12的总和,然后在第二步中添加缺少的数字以在每组中得到12
订单号 | 数字 |
---|---|
1 | 2.0 |
2 | 4.5 |
3 | 5.0 |
4 | 3.5 |
5 | 3.5 |
6 | 0.5 |
7 | 1.5 |
8 | 4.5 |
9 | 4.5 |
10 | 1.5 |
WITH cte AS (SELECT
order_num,
num,
SUM(num) OVER (ORDER BY order_num) AS cumulative_sum
FROM
`ms_jzs6s5.test_numbers`)
, groupHours as (
SELECT
order_num,
num,
cumulative_sum,
CASE
WHEN cumulative_sum <= CAST(12 AS FLOAT64) THEN num
ELSE num - GREATEST(cumulative_sum - CAST(12 AS FLOAT64), 0)
END AS plan,
IF(MOD(CAST(cumulative_sum AS NUMERIC), 12) <> 0, CEIL(cumulative_sum / 12), CEIL(cumulative_sum / 12) + 1) AS group_num AS group_num,
FROM
cte
)
, Lastgroup as (
SELECT
groupHours.*
FROM
groupHours
JOIN (
SELECT MAX(group_num) maxgroup
FROM groupHours
UNION ALL
SELECT MAX(group_num) - 1 maxgroup
FROM groupHours) ON groupHours.group_num = maxgroup
)
, groupLastHours as (
SELECT
group_num,
12 - SUM(num) AS lastHour
FROM
groupHours
GROUP BY group_num
)
(
SELECT 1 as iteration, *
FROM groupHours
UNION ALL
SELECT 2 iteration,
Lastgroup.*
FROM Lastgroup
LEFT JOIN (
SELECT
groupLastHours.group_num,
Lastgroup.num,
MIN(order_num) order_num,
FROM groupLastHours
LEFT JOIN Lastgroup ON lastHour = Lastgroup.num
GROUP BY
groupLastHours.group_num,
groupLastHours.lastHour,
Lastgroup.num
) lsh ON Lastgroup.num = lsh.num
)
ORDER BY group_num, iteration
这不是一个智能分组,但它会累积创建组,每组的总和不超过 12 ...
with t as (
select * from unnest([
struct(1 as order_num, 2.0 as num),
(2,4.5), (3,5.0), (4,3.5), (5,3.5), (6,0.5), (7,1.5), (8,4.5), (9,4.5), (10,1.5)
])
)
select *
,sum(num) over (order by order_num) as cumusum
,cast(floor(sum(num) over (order by order_num)/12) as int64) as g
,sum(num) over (order by order_num) - cast(floor(sum(num) over (order by order_num)/12) as int64)*12 as g_fill_sum
from t
也许有人可以将其变成更好的解决方案......