Window 可以比 2 个 CTE 更好地进行百分比计算的函数?
Window function that can do a percentage calculation better than 2 CTE's?
我试图通过首先在一个 CTE 中获取尺寸级别的总量,然后创建另一个 CTE 来获取文章级别的总量,从而计算一篇文章在整体尺寸级别的百分比。在下面的代码中,它似乎可以工作,但它也很长并且需要 运行。
我很好奇是否有更有效的方法,可能使用 OVER
或另一个 window 函数来获得相同的结果。我以前使用过 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
您可以使用 window 函数,对 Material 和大小求和,然后除以 material 的总和,得到每个 material 的每个大小的百分比:
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
我创建了一个示例 demo on 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
我试图通过首先在一个 CTE 中获取尺寸级别的总量,然后创建另一个 CTE 来获取文章级别的总量,从而计算一篇文章在整体尺寸级别的百分比。在下面的代码中,它似乎可以工作,但它也很长并且需要 运行。
我很好奇是否有更有效的方法,可能使用 OVER
或另一个 window 函数来获得相同的结果。我以前使用过 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
您可以使用 window 函数,对 Material 和大小求和,然后除以 material 的总和,得到每个 material 的每个大小的百分比:
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
我创建了一个示例 demo on 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