Я хочу заменить длинный подзапрос, который возвращает скалярное значение или не существует, просто коротким псевдонимом, потому что я помещаю его 3 раза в инструкцию UPDATE. Подзапрос принимает последнее значение в UncoveredLoss
, если оно есть, и новое значение UncoveredLoss
вычисляется в обновленной строке в зависимости от последнего значения UncoveredLoss
.
Это некоррелированный запрос, но он используется в предложении SELECT
, а не в предложении FROM
. Возможно, мне следует как-то изменить оператор UPDATE
в триггере.
Рабочий код:
CREATE TRIGGER Result
UPDATE OF Win ON Log
BEGIN
UPDATE Log
SET Profit = CASE
WHEN NEW.Win = 0
THEN - Stake
WHEN NEW.Win = 1
THEN Rate * Stake / 100
WHEN NEW.Win = 2
THEN 0
END
WHERE ID = OLD.ID;
UPDATE Log
SET SumProfit = (
SELECT Sum(Profit)
FROM (
SELECT StrategyAccountID
,Profit
FROM Log
WHERE DATE <= NEW.DATE
)
GROUP BY StrategyAccountID
HAVING StrategyAccountID = NEW.StrategyAccountID
)
WHERE ID = NEW.ID;
UPDATE Log
SET UncoveredLoss = CASE
WHEN EXISTS (
SELECT UncoveredLoss
FROM Log
WHERE DATE < NEW.DATE
AND StrategyAccountID = NEW.StrategyAccountID
ORDER BY DATE DESC LIMIT 1
)
AND (
SELECT UncoveredLoss
FROM Log
WHERE DATE < NEW.DATE
AND StrategyAccountID = NEW.StrategyAccountID
ORDER BY DATE DESC LIMIT 1
) + NEW.Profit < 0
THEN (
SELECT UncoveredLoss
FROM Log
WHERE DATE < NEW.DATE
AND StrategyAccountID = NEW.StrategyAccountID
ORDER BY DATE DESC LIMIT 1
) + NEW.Profit
WHEN NOT EXISTS (
SELECT UncoveredLoss
FROM Log
WHERE DATE < NEW.DATE
AND StrategyAccountID = NEW.StrategyAccountID
ORDER BY DATE DESC LIMIT 1
)
AND NEW.Profit < 0
THEN NEW.Profit
ELSE 0
END
WHERE ID = NEW.ID;
END;
Простая замена подзапроса с использованием CTE не работает:
CREATE TRIGGER Result
UPDATE OF Win ON Log
BEGIN
UPDATE Log
SET Profit = CASE
WHEN NEW.Win = 0
THEN - Stake
WHEN NEW.Win = 1
THEN Rate * Stake / 100
WHEN NEW.Win = 2
THEN 0
END
WHERE ID = OLD.ID;
UPDATE Log
SET SumProfit = (
SELECT Sum(Profit)
FROM (
SELECT StrategyAccountID
,Profit
FROM Log
WHERE DATE <= NEW.DATE
)
GROUP BY StrategyAccountID
HAVING StrategyAccountID = NEW.StrategyAccountID
)
WHERE ID = NEW.ID;
WITH Loss
AS (
SELECT UncoveredLoss
FROM Log
WHERE DATE < NEW.DATE
AND StrategyAccountID = NEW.StrategyAccountID
ORDER BY DATE DESC LIMIT 1
)
UPDATE Log
SET UncoveredLoss = CASE
WHEN EXISTS (Loss)
AND (Loss) + NEW.Profit < 0
THEN (Loss) + NEW.Profit
WHEN NOT EXISTS (Loss)
AND NEW.Profit < 0
THEN NEW.Profit
ELSE 0
END
WHERE ID = NEW.ID;
END;
Ошибка: рядом с «ОБНОВЛЕНИЕ»: синтаксическая ошибка
Это работает хорошо, когда я не заменяю подзапрос, но когда я пытаюсь использовать CTE, это терпит неудачу. Я работаю в режиме sql.el в Emacs.