在SQL中创建平均值并检测到高于x%的增长

在SQL中创建平均值并检测到高于x%的增长,sql,sql-server-2012,average,Sql,Sql Server 2012,Average,我想在SQLServer2012中创建以下内容:我发现最好的解释方法是使用表 我有购买日期、客户id和客户支付的价格,如下表所示: DateOnly Customer Price 2012/01/01 1 50 2012/01/01 2 60 2012/01/01 3 80 2012/01/02 4 40 2012/01/02 5 30 20

我想在SQLServer2012中创建以下内容:我发现最好的解释方法是使用表

我有购买日期、客户id和客户支付的价格,如下表所示:

DateOnly     Customer    Price
2012/01/01      1         50
2012/01/01      2         60      
2012/01/01      3         80
2012/01/02      4         40
2012/01/02      5         30
2012/01/02      1         55
2012/01/03      6         80
2012/01/04      2         90
然后,我需要做的是保存一份记录客户支付的平均价格的记录。具体如下:

DateOnly     Customer    Price    AveragePrice
2012/01/01      1         50           50
2012/01/01      2         60           60
2012/01/01      3         80           80
2012/01/02      4         40           40
2012/01/02      5         30           30
2012/01/02      1         55          52.5
2012/01/03      6         80           80 
2012/01/04      2         90           75
DateOnly     Customer    Price    AveragePrice
2012/01/04      2         90           75
最后,我需要选择导致客户支付的平均价格上涨超过10%的行

在这种情况下,客户2的第二个订单应该是唯一要选择的订单,因为它使该客户支付的平均价格增加了10%以上

因此,结果表应如下所示:

DateOnly     Customer    Price    AveragePrice
2012/01/01      1         50           50
2012/01/01      2         60           60
2012/01/01      3         80           80
2012/01/02      4         40           40
2012/01/02      5         30           30
2012/01/02      1         55          52.5
2012/01/03      6         80           80 
2012/01/04      2         90           75
DateOnly     Customer    Price    AveragePrice
2012/01/04      2         90           75
提前感谢您的帮助。

有趣的问题

通过从每行所有价格的总和中减去每行的价格,您可以得到不包含当前购买的平均值。此观察结果与窗口函数相结合,提供获取要查找的行所需的信息:

select *
from (select t.*,
             avg(price) over (partition by customer) as avgprice,
             sum(price) over (partition by customer) as sumprice,
             count(price) over (partition by customer) as cntprice
      from table1 t
     ) t
where (case when cntprice > 1
            then (sumprice - price) / (cntprice - 1) 
       end) > avgprice*1.1;

注意where子句中大小写的用法。有一个潜在的零除问题。SQL Server保证案例的when部分将在场景中的then部分之前进行评估。因此,这是安全的,不会出现这个问题。

第一个CTE是准备您的数据=为每个客户的购买分配行号,以便进一步用于连接

第二个CTE是递归的,它完成过程中的所有工作。第一部分是获取每个客户的第一次购买和下一次购买的递归部分联接,并计算TotalPrice、AveragePrice和Increase

最后,只需选择增长超过10%的行

WITH CTE_Prep AS 
(
    SELECT *, ROW_NUMBER() OVER (PARTITION BY Customer ORDER BY DateOnly) RN
    FROM Table1
)
,CTE_Calc AS
(
    SELECT *, Price AS TotalPrice, CAST(Price AS DECIMAL(18,2)) AS AveragePrice, CAST (0 AS DECIMAL(18,2)) AS Increase 
    FROM CTE_Prep WHERE RN = 1

    UNION ALL

    SELECT p.*
        , c.TotalPrice + p.Price AS TotalPrice 
        , CAST(CAST(c.TotalPrice + p.Price AS DECIMAL(18,2)) / p.RN AS DECIMAL(18,2)) AS AveragePrice
        , CAST(CAST(CAST(c.TotalPrice + p.Price AS DECIMAL(18,2)) / p.RN AS DECIMAL(18,2)) / c.AveragePrice AS DECIMAL(18,2)) AS Increase
    FROM CTE_Calc c
    INNER JOIN CTE_Prep p ON c.RN + 1 = p.RN  AND p.Customer = c.Customer
)
SELECT * FROM CTE_Calc
WHERE Increase > 1.10

谢谢你的回复!我试图在sqlfiddle上测试它,但在'@Alfons。固定的SQLFiddle帮助很大。