Как поставить переменную в WHERE из этого же запроса MySQL?

Есть вот такой запрос:

UPDATE `equiry_exchange_orders` SET available_amount_crypto_currency = CASE #Если заявка на обмен может быть выкуплена полностью WHEN (@total_paid := @total_paid + @cume_amount := (@sum := @sum - (initial_amount_equiry * 0.46656841)) + (initial_amount_equiry * 0.46656841)) is not null AND @cume_amount >= initial_amount_equiry * 0.46656841 THEN initial_amount_equiry * 0.46656841 #Если заявка на обмен может быть выкуплена только частично WHEN (@total_paid := @total_paid + @cume_amount := (@sum := @sum - (initial_amount_equiry * 0.46656841)) + (initial_amount_equiry * 0.46656841)) is not null AND @cume_amount < initial_amount_equiry * 0.46656841 THEN @cume_amount + (initial_amount_equiry * 0.46656841) END WHERE (@cume_amount) > 0 AND `type` = 'withdraw' ORDER BY `time_order_created` ASC

Суть запроса в следующем:
В таблице есть заявки на обмен. И есть изначально определенная сумма 0.46656841, которой нужно "выкупить" только те заявки, которые эта сумма сможет выкупить. То есть берется значение столбца "initial_amount_equiry" и смотрится, может ли сума 0.46656841 его "выкупить". Если может полностью, то в столбец "available_amount_crypto_currency" записывается значение из "initial_amount_equiry", а остаток суммы 0.46656841 сравнивается со значением столбца "initial_amount_equiry" следующей строки и опять проверяется - может ли уже остаток "выкупить" это полностью или нет. Если может, то так продолжается далее. А если сумма 0.46656841 может "выкупить" значение из "initial_amount_equiry" только частично, то рассчитывается сумма, которая по сути осталась от 0.46656841 и записывается в "available_amount_crypto_currency".

В настоящий момент запрос работает следующим образом: в заявки, которые сумма 0.46656841 может "выкупить" записываются положительными числа в колонку "available_amount_crypto_currency", а дальше в другие колонки записываются числовые значения уже со знаком "-" (минус).

Вопрос: как сделать так, чтобы минусовые значения не записывались? То есть записывалось только то, что реально может "выкупиться"? Для этого я пробую сделать WHERE (@cume_amount) > 0, но насколько я уже понял, то переменная @cume_amount еще равна нулю, так как возможно еще не посчитана на этом этапе запроса. Подскажите, как можно все-таки переменную @cume_amount использовать в WHERE или каким-либо другим образом "отсечь" минусовые значения? Важно, чтобы строки, где могут быть минусовые значения просто не попадали в UPDATE, именно для этого я и хотел использовать WHERE. Может быть есть другие решения?


Ответы (1 шт):

Автор решения: Mike
set @need = 210;
update equiry_exchange_orders o
  join (
    select id, new_avail, @need := @need - new_avail
      from (
        select *, case when remain >= 0 then init else @need - prev_sum end new_avail
          from (
            select *, sum(init) over(order by id)-init prev_sum, @need-sum(init) over(order by id) remain
              from equiry_exchange_orders
        ) x 
      ) y
    where new_avail > 0 for update
  ) n on o.id=n.id
  set avail = new_avail

На начало запроса в переменную @need помещается сумма которую необходимо списать. Запрос пишет в колонку avail сколько было списано из данной записи (полная сумма или остаток). После выполнения запроса в переменной @need остается сумма, на которую не хватило заявок. В order by внутри over указать желаемый порядок исполнения ордеров (сейчас по id записей)

Пример на dbfiddle.uk

→ Ссылка