计算超出和低于阈值的项目数

时间:2015-08-11 02:50:17

标签: mysql sql sql-server database hana

我试图找出一个类别中总销售额超过80%(阈值)的“最快”数量项目,以及一个类别中总销售额低于80%(阈值)的项目数量。

以下是原始数据集。

Category    Items   Sales
0001        1000    400
0001        1001    100
0001        1002    13
0001        1003    300
0001        1004    10
0001        1005    11
0001        1006    12
0001        1007    200
0001        1008    14
0001        1009    15

总销售额的8%(阈值)以上(860)。

Category     Number of item *above threshold
0001         3

对于类别0001,达到80%阈值的“最快”项目数为3,即1000,1003,1007,总计900(400 + 300 + 200)。

总销售额的8%(阈值)以下(860)。

Category     Number of item *below threshold
0001         7

对于类别0001,低于80%阈值的项目数为7,即1001,1002,1004,1005,1006,1008,1009。

我不确定这是否可以通过基于集合的解决方案实现,这些看起来像需要迭代才能找到最快且超过80%销售门槛的项目数量。

我可以找出类别的总销售额,因此占总销售额的80%,但我很难找到一个类别中总销售额超过80%(阈值)的“最快”数量的项目。任何人都知道怎么做?

如果您需要更多详细信息,请与我们联系。

此致 麦克

2 个答案:

答案 0 :(得分:0)

如果您使用的是SQL Server 2012 +:

SQL Fiddle

DECLARE @treshold NUMERIC(5, 2) = 0.80;

WITH Cte AS(
    SELECT *,
        ss = SUM(Sales) OVER(PARTITION BY Category ORDER BY Sales DESC)
    FROM tbl
)
SELECT
    c.Category,
    above = n,
    below = c.cnt - n
FROM(
    SELECT 
        Category, 
        cnt = COUNT(*),
        tresh = @treshold * SUM(Sales)
    FROM tbl GROUP BY Category
)c
OUTER APPLY(
    SELECT 
        n = COUNT(*)
    FROM Tbl
    WHERE Category = c.Category
    AND Sales >= (SELECT TOP 1 Sales FROM Cte WHERE ss >= c.tresh)
)a

<强> RESULT

| Category | above | below |
|----------|-------|-------|
|     0001 |     3 |     7 |

答案 1 :(得分:0)

几乎可以在任何DMBS上运行的解决方案(在MySQL和Oracle上测试,也适用于PostgreSQL,SQL Server和SQLite,但是你必须注意你没有使用整数除法[可以将累计销量乘以1.0]使它真正在所有这些上运行]):

SELECT
   O.Category,
   SUM(CASE WHEN O.CumulativeSales / O.TotalSales < 1 - Thresh THEN 0 ELSE 1 END) Above,
   SUM(CASE WHEN O.CumulativeSales / O.TotalSales < 1 - Thresh THEN 1 ELSE 0 END) Under
FROM
   (SELECT
      T.Category,
      (SELECT
         SUM(Sales)
      FROM
         ...
      WHERE
         Sales <= T.Sales AND Category = T.Category
      ) AS CumulativeSales,
      (SELECT
         SUM(Sales)
      FROM
         ...
      WHERE
         Category = T.Category
      ) AS TotalSales
   FROM
      ... T
   ) O
GROUP BY
   O.Category
;