Чем заменить `WITH RECURISVE` в триггере?

У меня имеется следующая таблица (рис. 1), и мне надо поддерживать правильные значения для поля price у категорий (is_category = 1), которые для них вычисляются как средняя цена всех ее товаров, включая товары дочерних категорий.

Для этого я первоначально создал следующие триггеры, которые работают, но вычисляют неправильные значения уже для категорий второго уровня (например, «Товары»), так как считают среднее от цен категорий-потомков, а не от товаров:

pragma recursive_triggers=ON;
CREATE TRIGGER tr_update_price_insert
AFTER INSERT ON shop_units WHEN NEW.parent_id IS NOT NULL AND NEW.is_category = 0
BEGIN
    UPDATE
        shop_units
    SET
        price = (SELECT AVG(price) FROM shop_units WHERE parent_id = NEW.parent_id)
    WHERE
        id = NEW.parent_id;
END;

CREATE TRIGGER tr_update_price_update
AFTER UPDATE OF price ON shop_units WHEN NEW.parent_id IS NOT NULL
BEGIN
    UPDATE
        shop_units
    SET
        price = (SELECT AVG(price) FROM shop_units WHERE parent_id = NEW.parent_id)
    WHERE
        id = NEW.parent_id;
END;

Мне пришла идея использовать WITH RECURSIVE для того, чтобы рекурсивно собирать всех потомков, и я написал следующий код, который должен вычислять правильные значения:

...
CREATE TRIGGER tr_update_price_insert
AFTER INSERT ON shop_units WHEN NEW.parent_id IS NOT NULL AND NEW.is_category = 0
BEGIN
WITH RECURSIVE
    child_ids(identifier) AS (
        SELECT NEW.parent_id
        UNION
        SELECT
            id
        FROM
            shop_units, child_ids
        WHERE
            shop_units.parent_id=child_ids.identifier
    )
UPDATE
    shop_units
SET
    price = (SELECT AVG(price) AS price FROM shop_units INNER JOIN child_ids ON shop_units.id = child_ids.identifier WHERE is_category = 0)
WHERE
    id = NEW.parent_id;
END;
...

Но который не работает из-за того, что WITH запрещен в триггерах. Я долго думал и гуглил, но так и не смог придумать, как переписать этот триггер, чтобы он считал все корректно. Как это можно сделать?


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