Оконная функция, которая может сделать процентный расчет лучше, чем 2 CTE? - PullRequest
0 голосов
/ 25 января 2020

Я пытаюсь рассчитать процентную долю товара на уровне размера целого, сначала получив общее количество на уровне размера в одном CTE, а затем создав другой CTE, чтобы получить общее количество только на уровне товара. В приведенном ниже коде, кажется, работает, но это также довольно долго и требует времени для запуска.

Мне любопытно, есть ли более эффективный способ, возможно, использующий OVER или другую оконную функцию для получения того же результата. Я использовал OVER раньше, но так как они на разных уровнях детализации, я не совсем уверен.

SQL:

WITH      SumByMaterialCTE (MATERIAL, QUANTITY) --used to get the sum of quantity of an article for all demand 

AS    (SELECT MATERIAL, SUM(QUANTITY) 
                             FROM VW_MRP_ALLOCATION_COMBINED
                             WHERE REQUIREMENT_TYPE <> ''
                             GROUP BY MATERIAL), 

       DemandSizeLevelCTE (MATERIAL, SIZE_LITERAL, SIZE_PERCENT) --used to get a percentage for each size of an article over the total demand

AS     (SELECT DS.MATERIAL, 
               DS.SIZE_LITERAL,
               (SUM(DS.QUANTITY)/SM.QUANTITY) AS 'SIZE_PERCENT'
        FROM VW_MRP_ALLOCATION_COMBINED DS
        JOIN SumByMaterialCTE SM ON DS.MATERIAL = SM.MATERIAL
        WHERE DS.REQUIREMENT_TYPE <> '' 
        GROUP BY DS.MATERIAL, DS.SIZE_LITERAL, SM.QUANTITY)


SELECT DS.MATERIAL, 
       DS.SIZE_LITERAL, 
       DS.SIZE_PERCENT 

FROM   DemandSizeLevelCTE DS

1 Ответ

1 голос
/ 25 января 2020

Вы можете использовать оконные функции, суммируя по материалу и размеру и деля на сумму по материалу, чтобы получить проценты каждого размера для каждого материала:

SELECT DISTINCT MATERIAL, SIZE_LITERAL,
       SUM(QUANTITY) OVER (PARTITION BY MATERIAL, SIZE_LITERAL) AS TOTAL_SIZE,
       SUM(QUANTITY) OVER (PARTITION BY MATERIAL) AS TOTAL_MATERIAL,
       100.0 * SUM(QUANTITY) OVER (PARTITION BY MATERIAL, SIZE_LITERAL) /
       SUM(QUANTITY) OVER (PARTITION BY MATERIAL) AS SIZE_PERCENT
FROM VW_MRP_ALLOCATION_COMBINED
ORDER BY MATERIAL, SIZE_LITERAL

Я создал образец демонстрация по SQLFiddle , для которой вывод:

MATERIAL    SIZE_LITERAL    TOTAL_SIZE  TOTAL_MATERIAL  SIZE_PERCENT
COTTON      L               3           22              13.636363636363
COTTON      M               11          22              50
COTTON      S               8           22              36.363636363636
NYLON       L               10          19              52.631578947368
NYLON       M               2           19              10.526315789473
NYLON       S               4           19              21.052631578947
NYLON       XL              3           19              15.78947368421
...