Ограниченная текущая сумма в Bigquery

У меня есть база данных с идентификатором 3 столбцов, датой, суммой

ИДЕНТИФИКАТОР дата количество 1 2020-01-01 2 2 2020-01-03 5 3 2020-01-08 10 4 2020-01-12 -9 5 2020-01-12 3

Я хотел бы сделать простую текущую сумму, которая будет ограничена 10, а затем перезапустится сразу после этого, поэтому столбец, который я ищу, будет:

ИДЕНТИФИКАТОР дата количество результат 1 2020-01-01 2 2 2 2020-01-03 5 7 3 2020-01-08 10 10 4 2020-01-12 -9 1 5 2020-01-12 3 4

Большинство уже существующих ответов включают рекурсивные запросы, которые невозможны в Big Query, поэтому я открыт для любой идеи.

сколько строк в вашей таблице?

Mikhail Berlyant 11.12.2020 07:46

У меня 5,6 млн строк

Belkachait08 11.12.2020 07:53

есть ли шанс, что у вас есть что-то для разделения - например, по дням или месяцам?

Mikhail Berlyant 11.12.2020 07:54

Таблица уже разделена по дате. В худшем случае я разобью таблицу на несколько небольших таблиц по идентификаторам

Belkachait08 11.12.2020 08:12

я имел в виду раздел для использования в логике укупорки

Mikhail Berlyant 11.12.2020 08:14

Нет, у меня действительно нет другого способа разделить мои таблицы, кроме идентификатора. (У меня много разных идентификаторов, так что все должно быть в порядке)

Belkachait08 11.12.2020 08:17

А что, если «10» там нет, а есть 11 или 12? Как выглядят результаты?

Gordon Linoff 11.12.2020 15:02

все равно будет 10

Belkachait08 11.12.2020 16:13
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
8
328
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Использование javascript UDF может помочь. Поскольку то, что вы на самом деле хотите, - это способ рассчитать текущую сумму, следуя нескольким правилам (т.е. добавить каждое положительное число и сохранить максимум суммы или 10, однако, если число отрицательное, сбросьте и вычтите из суммы). Эта логика может быть инкапсулирована в UDF и применена к массиву, который объединяет все суммы до заданного дня.

Я не совсем уверен, как это будет масштабироваться для вашего набора данных из 5,6 млн строк, но для приведенного выше примера он вычисляет желаемую ограниченную текущую сумму.

#standardSQL
CREATE TEMP FUNCTION calculate_sum(arr ARRAY<INT64>)
RETURNS INT64
LANGUAGE js AS """
  var sum = 0;
  for (var element in arr) {
    if (+arr[element] >= 0) {
     sum += +arr[element];
     sum = Math.min(sum, 10);
    } else if (+arr[element] < 0) {
     sum += +arr[element]
    }
  }
  return sum;
""";

WITH temp AS (
  SELECT 1 id, DATE("2020-01-01") date ,  2 AS amount UNION ALL
  SELECT 2, DATE("2020-01-03"),  5 UNION ALL
  SELECT 3, DATE("2020-01-08"),  10 UNION ALL
  SELECT 4, DATE("2020-01-12"),  -9 UNION ALL
  SELECT 5, DATE("2020-01-12"),  3
),
base AS (
SELECT date, amount, 
ARRAY_AGG(amount) OVER(ORDER BY id, date) AS t
FROM temp)
SELECT date, amount, calculate_sum(t) capped_sum FROM base

Что даст

Ряд дата количество capped_sum 1 2020-01-01 2 2 2 2020-01-03 5 7 3 2020-01-08 10 10 4 2020-01-12 -9 1 5 2020-01-12 3 4

Другие вопросы по теме