running — итог, который переносится по колонке
Когда нужен: значение не разыгрывается, а накапливается: остаток на счёте после каждой операции, счётчик, который только растёт, самая большая нагрузка за всё время. Значение сороковой строки зависит от строк с первой по тридцать девятую.
Все остальные генераторы отвечают на строку по её номеру. Этот не может — и это не ограничение, которое надо обходить, а ровно то, что слово «нарастающий» и значит.
<tdc>
<env count="8" seed="ledger" local="en">
<sequence name="Op"><gen type="number" value="-400..500"/></sequence>
<sequence name="Balance"><gen type="running" of="Op" accumulate="sum" base="1000"/></sequence>
</env>
<block>
<line><data>${{Op}} ${{Balance}}</data></line>
</block>
</tdc>
399 1399 -246 1153 -270 883 159 1042 24 1066 -400 666 419 1085 80 1165
Значения получены с фиксированным seed, то есть воспроизводимы, но точные строки могут
отличаться между версиями ядра. Смотрите на форму, а не на конкретные символы.
Коротко
| Атрибут | Обязателен | Что делает |
|---|---|---|
of | да | Колонка, которую накапливаем. Должна быть объявлена выше этой последовательности |
accumulate | да | sum, min или max |
base | нет | Начальное значение — входящий остаток, начальный пробег |
reset | нет | Колонка, смена значения которой перезапускает итог |
Нарастающий итог ничего не разыгрывает. Он читает уже существующую колонку, не расходует ни одного случайного числа — и потому добавление такой колонки не сдвигает ни одну другую.
reset= — свой итог на каждую группу
Без reset= итог один на весь файл. С ним колонка делится на отрезки, и каждый
накапливается сам по себе — остаток по счёту, а не остаток по запуску.
<env count="9" seed="acct" local="en">
<sequence name="Account"><gen type="text" value="A,A,A,B,B,C,C,C,C" order="sequential"/></sequence>
<sequence name="Op"><gen type="number" value="10..99" decimals="2"/></sequence>
<sequence name="Balance"><gen type="running" of="Op" accumulate="sum" reset="Account"/></sequence>
</env>
A 96.47 96.47 A 29.18 125.65 A 91.43 217.08 B 15.65 15.65 B 67.87 83.52 C 48.03 48.03 C 39.00 87.03 C 56.04 143.07 C 78.62 221.69
Отрезок кончается там, где значение reset= изменилось по сравнению с прошлой
строкой, — значит, группы должны идти подряд. order="sequential" выше это один способ;
сортировка другой, но сортировкой обычно занимается база,
так что чаще всего колонка и так приходит сгруппированной.
Точные копейки
Арифметика идёт на целых числах, умноженных на самую широкую дробь в колонке, и ни разу
не на плавающей точке. 96.47 + 29.18 это 125.65 — и это одно и то же 125.65 во всех
пяти реализациях, чего плавающая точка не гарантирует.
base= участвует в том же масштабе. Входящий остаток 1000.00 расширяет всю колонку до
двух знаков — именно так, как ожидает тот, кто читает выписку.
Порядок объявления
of= и reset= называют колонку, и обе должны быть объявлены выше нарастающего итога
(TDC240). Причина та же, что у parent: итог
строится из колонки, которая уже существует.
error[TDC240]: of="Op" is not a sequence declared above this one --> ledger.tdc:3:54 | 3 | <sequence name="Balance"><gen type="running" of="Op" accumulate="sum"/></sequence> | ^^ | note: A running total is built from a column that already exists, so the column it reads has to come first.
Нарастающий итог, который не сказал, что и как накапливать, — это TDC239.
На каком движке это считается
Потоковые движки отказываются считать нарастающий итог — прямо называя его — и маршрутизатор отправляет конфигурацию на движок в памяти:
tdcv2: a running total ("Balance") is the accumulation of every row before it, so it cannot be computed one row at a time; the in-memory engine handles it (run without a forced streaming engine)Обычно этого сообщения вы не увидите: движок выбирает маршрутизатор, а отказ всплывает только тогда, когда конфигурация назвала потоковый движок сама — то есть попросила, чтобы ей сказали.
Чего это стоит: нарастающий итог живёт в памяти весь запуск, как любая колонка движка в памяти. Это честная граница этого генератора. Выписка на несколько миллионов строк — нормально; выписка на миллиард строк — не то, что делает TDC, потому что весь смысл потоковых движков в том, что строка считается по своему номеру, а здесь — не считается.
Всё остальное по-прежнему течёт потоком. Ограничение действует на конфигурацию, а не
на проект: запуск без нарастающего итога не затронут, а нарастающий итог внутри одной
записи —
accumulate= на списке repeat — не стоит вообще ничего и работает на любом движке.
См. также
accumulate=на спискеrepeat— та же идея внутри одной записи, бесплатно на любом движке- Счётчики —
incrementиdecrement: они двигаются фиксированным шагом и считаются по номеру строки - Временные ряды — кривая с трендом и шумом, тоже по одному номеру строки, и обычно это и есть то, что нужно, когда говорят «значение, которое растёт»