Я не уверен, что мне нужен именно рекурсивный запрос, но это то, что я пытаюсь сделать (запрос A, который вызывает запрос B, который вызывает запрос A ... рекурсивно).
Это мой минимальный полный проверяемый код:
У меня есть такая таблица (MySQL v5.7, InnoDB):
CREATE TABLE transactions
(
id INT PRIMARY KEY AUTO_INCREMENT,
code VARCHAR(10),
date DATETIME,
mode ENUM('Buy', 'Sell', 'Count', 'Return'),
quantity INT,
price DECIMAL(10,2),
price_currency ENUM('ARS', 'USD'),
usd_to_ars DECIMAL(10,2),
return_id INT NULL DEFAULT NULL
)
А затем я заполняю ее некоторыми элементами:
INSERT INTO transactions (code, date, mode, quantity, price, price_currency, usd_to_ars)
VALUES
("a", "20180101", 'Buy', 4, 10, 'ARS', 3.7),
("a", "20180102", 'Buy', 9, 8, 'ARS', 5.8),
("a", "20180103", 'Sell', -3, 0, 'USD', 0),
("b", "20180104", 'Buy', 5, 5, 'USD', 8.9),
("a", "20180105", 'Buy', 2, 7, 'USD', 3.4),
("b", "20180106", 'Buy', 1, 8, 'ARS', 9),
("a", "20180107", 'Sell', -8, 0, 'USD', 4.4),
("a", "20180108", 'Buy', 9, 9, 'ARS', 3.2);
INSERT INTO transactions (code, date, mode, quantity, price, price_currency, usd_to_ars, return_id)
VALUES ("a", "20180109", 'Return', 6, 2, 'ARS', 2, 2);
Наконец-то я выполняю этот код:
SELECT *
FROM
(SELECT
id, date, code, mode, quantity, price, price_currency, usd_to_ars, return_id,
@acm := @acm + quantity as stock,
@avr := (@avr * (@acm - quantity) +
if(quantity > 0, quantity *
if(mode = "Return", @avr,
if(price_currency = 'USD', price, price / usd_to_ars)
),
quantity * @avr)
) / @acm as average_price_usd
FROM
transactions t1,
(SELECT @acm := 0) x,
(SELECT @avr := 0) y) t2
ORDER BY id DESC
dbfiddle.uk
Как видите, это не вызывает ошибки, этовозвращает таблицу, она работает ... но не так, как я хочу.
В четвертой строке:
@avr := (@avr * (@acm - quantity) + if(quantity > 0, quantity * if(mode = "Return", @avr, if(price_currency = 'USD', price, price / usd_to_ars)), quantity * @avr)) / @acm as average_price_usd
Я хотел бы изменить параметр @avr
для:
If(mode = "Return", @avr, [...])
В настоящий момент, если mode = "Return"
равно true
, используется текущее значение @avr
, но я бы хотел использовать значение @avr
записи, где id = return_id
.И из-за @avr
является вычисленным значением, я должен выполнить подзапрос, чтобы вычислить его снова ... Я думаю.Проблема в том, что я понятия не имею, как это сделать.
Итак, средняя цена id = 9
не должна быть 3.02...
, вместо этого это должно быть что-то вроде 2.72...
.
Итак, как я могу выполнить этот запрос внутри другого запроса, когда mode = "Return"
, чтобы получить @avr
значение записи WHERE subquery.id = return_id
?
Если это возможно, я новичок в SQL, поэтому я все еще не уверен, какие вещи возможны, а какие невозможны.Для меня не имеет значения, нужно ли мне создать столбец в таблице, представлении или функции, я думаю, что справлюсь с любым из них.