SQL-запрос для создания текущего баланса под рукой?

В Teradata у меня есть запрос, который возвращает дату, начальные данные, продажи и поставки.

SELECT
 date, initial, sales, deliveries
FROM sample

Я хотел бы создать новый столбец, который действует как текущий баланс на руках, где расчет BOH = начальный - продажи + поставки. Однако расчет boh не должен начинаться до первой даты, когда начальная дата не равна нулю.

Ниже в идеале показано, что должен возвращать столбец boh. Как мне структурировать запрос для этого?

date  initial  sales  deliveries   boh
---------------------------------------
01-01    0       2        4         0       
01-02    0       0        0         0
01-03    3       1        0         2
01-04    0       4        8         6
01-05    0       2        2         6
01-06    0       1        3         8
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
0
55
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

У меня нет под рукой базы данных Teradata, поэтому я выполнил следующий запрос в PostgreSQL:

select x.*,
  sum(case when mi <> 0 then initial - sales + deliveries else 0 end) 
    over(order by date) as boh
from (
  select t.*, max(initial) over(order by date) as mi
  from t
) x

Результат:

 date   initial  sales  deliveries  mi  boh 
 ------ -------- ------ ----------- --- --- 
 01-01  0        2      4           0   0   
 01-02  0        0      0           0   0   
 01-03  3        1      0           3   2   
 01-04  0        4      8           3   6   
 01-05  0        2      2           3   6   
 01-06  0        1      3           3   8   

См. пример выполнения в db<>fiddle.

Для Teradata для спецификации окна как для SUM, так и для MAX потребуются СТРОКИ МЕЖДУ НЕОГРАНИЧЕННОЙ ПРЕДЫДУЩЕЙ И ТЕКУЩЕЙ СТРОКОЙ, чтобы получить указанные результаты.

Fred 17.04.2024 02:44

Согласно Teradata Docs это фрейм окна по умолчанию, поэтому необходимости объявлять его не должно быть.

The Impaler 17.04.2024 05:45

@TheImpaler - Я думаю, ты неправильно читаешь документацию. Для Teradata значением по умолчанию является ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING. При этом я всегда указываю свои окна, потому что Teradata здесь отличается от ANSI.

Andrew 17.04.2024 15:52

@ Эндрю, я исправлен.

The Impaler 17.04.2024 18:04
Ответ принят как подходящий

Вы можете вычислить самую раннюю дату и использовать ее, чтобы определить, следует ли выполнять расчет.

SELECT 
"date", "initial", "sales", 
SUM(CASE WHEN "date" >= (SELECT MIN("date") FROM tmytable WHERE initial > 0) 
  then  ("initial" - sales + deliveries) 
  ELSE 0 END) OVER(ORDER bY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) boh
FROM tmYtable
дата исходный продажи бох 01-01 0 2 0 01-02 0 0 0 01-03 3 1 2 01-04 0 4 6 01-05 0 2 6 01-06 0 1 8
SELECT 6

рабочий пример

Для Teradata группа агрегации по умолчанию — СТРОКИ МЕЖДУ НЕОГРАНИЧЕННЫМИ ПРЕДЫДУЩИМИ И НЕОГРАНИЧЕННЫМИ ПОСЛЕДУЮЩИМИ, поэтому для получения желаемой совокупной суммы OVER( ORDER BY "date" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW )

Fred 17.04.2024 02:40

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