Postgresql для цикла для анализа ABC - PullRequest
0 голосов
/ 28 февраля 2019

Я пытаюсь сделать анализ ABC.Я должен классифицировать проданные товары внутри группы, к которой они принадлежат.Таким образом, SQL, с помощью которого я пытаюсь достичь этого, - вот этот.Запрос начинает выполняться, но даже если я оставлю его на несколько часов, он не даст никакого результата и не завершится.Когда я пробую тот же запрос, но без цикла - только с одной группой, все в порядке.Может ли кто-нибудь помочь мне выяснить, что не так с петлей.Спасибо:)

DO $$
DECLARE v integer;
BEGIN

FOR v in select id_group from ft_sales
LOOP

WITH ProductSales AS
(
    -- Get the total for each Product Model
    SELECT 
       id_group,
        id_article,
        SUM(qty) Sales
    FROM ft_sales
    WHERE id_date>2190  
GROUP BY
    id_group,
    id_article

)
-- Calculate culmulative total and categorise it based on the percentage.
-- Product Model that have high sales amount and make up the first 70% 
-- will be classified as A, the next 20% is B and the rest is C.
-- Product Models in A generate more revenue.
INSERT INTO classification ( id_group,id_article, sales, cum_sales, total, cum_perc, class )
SELECT ps.id_group,
    ps.id_article, 
    ps.Sales,
    SUM(ps.Sales) OVER (ORDER BY ps.Sales DESC) AS CumulativeSales,
    SUM(ps.Sales) OVER () AS TotalSales,
    SUM(ps.Sales) OVER (ORDER BY ps.Sales DESC) / SUM(ps.Sales) OVER () AS CumulativePercentage,
    CASE
        WHEN SUM(ps.Sales) OVER (ORDER BY ps.Sales DESC) / SUM(ps.Sales) OVER () <= 0.7 
            THEN 'A'
        WHEN SUM(ps.Sales) OVER (ORDER BY ps.Sales DESC) / SUM(ps.Sales) OVER () <= 0.9 
            THEN 'B'
        ELSE 'C'
    END AS Class
FROM    ProductSales ps
GROUP BY ps.id_group,
    ps.id_article,
    ps.Sales;
END LOOP;
    END $$; 

1 Ответ

0 голосов
/ 28 февраля 2019

Это может сработать для вас. Отказ от ответственности: Не проверено.Цель состоит в том, чтобы выбрать только необходимую информацию один раз , а затем зациклить ее для вставки.

DO
$$
DECLARE
    rec record;
BEGIN
    FOR rec IN
        SELECT  ps.id_group
                , ps.id_article
                , ps.Sales
                , SUM(ps.sales) OVER (ORDER BY ps.sales DESC) AS cumulative_sales
                , SUM(ps.sales) OVER () AS total_sales
                , SUM(ps.sales) OVER (ORDER BY ps.Sales DESC) / SUM(ps.Sales) OVER() AS cum_perc
                , CASE
                     WHEN SUM(ps.sales) OVER (ORDER BY ps.sales DESC) / SUM(ps.sales) OVER() <= 0.7 
                         THEN 'A'
                     WHEN SUM(ps.sales) OVER (ORDER BY ps.sales DESC) / SUM(ps.sales) OVER() <= 0.9 
                         THEN 'B'
                     ELSE 'C'
                  END AS class
        FROM
        (
            SELECT  id_group
                   , id_article
                   , SUM(qty) AS sales
            FROM ft_sales
            WHERE id_date > 2190
            GROUP BY id_group, id_article
        ) ps
    LOOP
        INSERT INTO classification ( id_group,id_article, sales, cum_sales, total, cum_perc, class )
        VALUES (rec.id_group, rec.id_article, rec.sales, rec.cumulative_sales, rec.total_sales, rec.cum_perc, rec.class)
    END LOOP;
END;
$$
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...