使用 SQL 获取累计百分比的起点
Getting the starting point of a cumulative Percent of Total using SQL
我需要根据他们的 "Percent of Total" 是什么来 return 记录。因此,例如,我可能想知道 "Top 10% of Sales by Customer".
目前,我正在使用这个:
SELECT * FROM (SELECT Dim1, SUM(SQ_Fact1) AS Fact1,
(SUM(SUM(SQ_Fact1)) OVER(ORDER BY SUM(SQ_Fact1) DESC))/SUM(SUM(SQ_Fact1)) OVER() AS PctOfTtl
FROM (SELECT Customer AS Dim1, SUM(Sales) AS SQ_Fact1
FROM SalesHistory GROUP BY Customer) AS sq
GROUP BY Dim1) AS mq
WHERE PctOfTtl<=0.10
这有点过于复杂,但它是查询构建的一部分 UI,因此它会为所有查询创建一个子查询和 "main" 外部查询(出于与此无关的原因),然后它必须围绕这些使用另一个外部查询来检查 PctOfTtl。无论如何,获取总数的累计百分比(并将其降序排序,因此我可以获得 "top" 记录)的行是:
(SUM(SUM(SQ_Fact1)) OVER(ORDER BY SUM(SQ_Fact1) DESC))/SUM(SUM(SQ_Fact1)) OVER() AS PctOfTtl
然后在外部查询中,我通过说 "WHERE PctOfTtl<=0.10"
来限制我 return 的总百分比
问题是,PctOfTtl 告诉我他们占总百分比的结束位置,而不是开始位置。
所以,假设顶级客户占销售额的 15%。它的 PctOfTtl 将为 0.15。问题是,如果用户要求 Customers in the Top 10% of Sales (<=0.1),它将 return 没有记录,因为最顶层的 Customer 直到 0.15 才 "end",所以他们的 PctOfTtl 不会 <=0.1。我需要知道的是他们占总数的百分比从哪里开始(即最顶级的客户将从 0 开始,第二个将从 0.15 开始,等等)。我真正要寻找的是总百分比 "range" 落在用户指定百分比范围内的任何客户(即使它超出了它)。
问题是,就像我说的,这是为了构建查询 UI,所以我无法完全重构查询来执行此操作。它必须在现有 "subquery/main query" 格式的范围内工作,而使用 "OVER" 子句就可以。我可以检查他们是否正在使用 "Top %" 过滤器,如果是,则添加 PctOfTtl 列并用限制 PctOfTtl 的外部查询包围查询。基本上,我希望找到一种使用 OVER() 的方法,它将告诉我 PctOfTtl 减去 PctOfTtl "before" 是什么。
尝试减去当前值:
SELECT *
FROM (SELECT Dim1, SUM(SQ_Fact1) AS Fact1,
SUM(SQ_Fact1) / SUM(SUM(SQ_Fact1)) OVER () as PctOfTtl
(SUM(SUM(SQ_Fact1)) OVER (ORDER BY SUM(SQ_Fact1) DESC))/SUM(SUM(SQ_Fact1)) OVER () AS Running_PctOfTtl
FROM (SELECT Customer AS Dim1, SUM(Sales) SQ_Fact1
FROM SalesHistory
GROUP BY Customer
) sq
GROUP BY Dim1
) mq
WHERE Running_PctOfTtl - PctOfTtl < 0.10;
我需要根据他们的 "Percent of Total" 是什么来 return 记录。因此,例如,我可能想知道 "Top 10% of Sales by Customer".
目前,我正在使用这个:
SELECT * FROM (SELECT Dim1, SUM(SQ_Fact1) AS Fact1,
(SUM(SUM(SQ_Fact1)) OVER(ORDER BY SUM(SQ_Fact1) DESC))/SUM(SUM(SQ_Fact1)) OVER() AS PctOfTtl
FROM (SELECT Customer AS Dim1, SUM(Sales) AS SQ_Fact1
FROM SalesHistory GROUP BY Customer) AS sq
GROUP BY Dim1) AS mq
WHERE PctOfTtl<=0.10
这有点过于复杂,但它是查询构建的一部分 UI,因此它会为所有查询创建一个子查询和 "main" 外部查询(出于与此无关的原因),然后它必须围绕这些使用另一个外部查询来检查 PctOfTtl。无论如何,获取总数的累计百分比(并将其降序排序,因此我可以获得 "top" 记录)的行是:
(SUM(SUM(SQ_Fact1)) OVER(ORDER BY SUM(SQ_Fact1) DESC))/SUM(SUM(SQ_Fact1)) OVER() AS PctOfTtl
然后在外部查询中,我通过说 "WHERE PctOfTtl<=0.10"
来限制我 return 的总百分比问题是,PctOfTtl 告诉我他们占总百分比的结束位置,而不是开始位置。
所以,假设顶级客户占销售额的 15%。它的 PctOfTtl 将为 0.15。问题是,如果用户要求 Customers in the Top 10% of Sales (<=0.1),它将 return 没有记录,因为最顶层的 Customer 直到 0.15 才 "end",所以他们的 PctOfTtl 不会 <=0.1。我需要知道的是他们占总数的百分比从哪里开始(即最顶级的客户将从 0 开始,第二个将从 0.15 开始,等等)。我真正要寻找的是总百分比 "range" 落在用户指定百分比范围内的任何客户(即使它超出了它)。
问题是,就像我说的,这是为了构建查询 UI,所以我无法完全重构查询来执行此操作。它必须在现有 "subquery/main query" 格式的范围内工作,而使用 "OVER" 子句就可以。我可以检查他们是否正在使用 "Top %" 过滤器,如果是,则添加 PctOfTtl 列并用限制 PctOfTtl 的外部查询包围查询。基本上,我希望找到一种使用 OVER() 的方法,它将告诉我 PctOfTtl 减去 PctOfTtl "before" 是什么。
尝试减去当前值:
SELECT *
FROM (SELECT Dim1, SUM(SQ_Fact1) AS Fact1,
SUM(SQ_Fact1) / SUM(SUM(SQ_Fact1)) OVER () as PctOfTtl
(SUM(SUM(SQ_Fact1)) OVER (ORDER BY SUM(SQ_Fact1) DESC))/SUM(SUM(SQ_Fact1)) OVER () AS Running_PctOfTtl
FROM (SELECT Customer AS Dim1, SUM(Sales) SQ_Fact1
FROM SalesHistory
GROUP BY Customer
) sq
GROUP BY Dim1
) mq
WHERE Running_PctOfTtl - PctOfTtl < 0.10;