Вычисление состояния детализации стека FIFO с помощью рекурсивного выбора SQLITE - PullRequest
0 голосов
/ 30 марта 2019

Мне нужно рассчитать точное содержание кормового бункера.Существует несколько типов каналов, и бункер имеет тип FIFO - канал, заполненный первым, используется первым.

В базе данных SQLite у меня есть две таблицы.Таблица состояние содержит ежедневную информацию о количестве корма в бункере на конец дня (2 поля = дата, количество).В этой таблице нет информации о типе фида.

Вторая таблица fill содержит информацию о заполнении стека (3 поля = fill_date, fill_amount, feed_type).

Мне нужно точно рассчитать, сколько из какого типа фида было в бункере за каждый день.

Я использую этот рекурсивный запрос:

  with recursive st (date, amount, feed_type, days_ago, rest) as (
      select
          date,
          case when fill_amount is null then 0 else MIN( amount, fill_amount ) end as amount,
          feed_type,
          1 as days_ago,
          case when fill_amount is null then amount else MAX( 0, amount - fill_amount ) end as rest
          from state s left join filling f on s.date=f.fill_date
      union
      select
          date,
          case when fill_amount is null then 0 else MIN( rest, fill_amount ) end as amount,
          f.feed_type,
          days_ago+1 as days_ago,
          case when fill_amount is null then rest else MAX(0, rest - fill_amount) end as rest
          from st left join filling f on st.date-st.days_ago=f.fill_date
          where st.rest>0 and st.days_ago<100
  ) select * from st where amount>0

Запрос сначала ищет, был ли бункер заполнен вв тот же день (при первоначальном выборе), затем за день до, за 2 дня до и т. д. (в следующих рекурсиях).Если бункер был заполнен, то рассчитывается, какая часть содержимого бункера относится к этому заполнению и есть ли неопознанный остаток.Остальное идентифицируется в следующей рекурсии.

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

Но я боюсь производительности, потому что для одноготребуемая запись требуется несколько рекурсий в зависимости от того, сколько дней назад был заполнен бункер.

Есть идеи о более эффективном решении?

...