SQL,使用Group by直到特定趋势(递增,递减,相同)

时间:2016-04-06 10:16:41

标签: sql-server sql-server-2014

我想知道如何修改我的代码,以便将假设10的所有相同值都视为UP,直到它递增然后降低为递减,如果没有变化则直到没有变化时为止。在值(增量,减量,相同)中。

这是我的代码:

;with etape1 as
    (
select ROW_NUMBER() OVER(ORDER BY mnth) AS id,* from [InsideTSQL2008].[alioune].[Sales]
    )
    ,
 etape2 as
 (
 select 
    a.id, b.mnth AS START , a.mnth AS FINISH , 
   a.qty - b.qty AS TREND
FROM
   etape1 a
   LEFT  JOIN etape1 b
   on a.id = b.id+1
   )
   select * from etape2;

我的结果是:

id  START       FINISH      TREND
1   NULL        2007-12-01  NULL
2   2007-12-01  2008-01-01  10
3   2008-01-01  2008-02-01  10
4   2008-02-01  2008-03-01  10
5   2008-03-01  2008-04-01  10
6   2008-04-01  2008-05-01  0
7   2008-05-01  2008-06-01  -10
8   2008-06-01  2008-07-01  -10
9   2008-07-01  2008-08-01  -10
10  2008-08-01  2008-09-01  -10
11  2008-09-01  2008-10-01  10
12  2008-10-01  2008-11-01  -10
13  2008-11-01  2008-12-01  20
14  2008-12-01  2009-01-01  10
15  2009-01-01  2009-02-01  10
16  2009-02-01  2009-03-01  -40

我的最终结果应该是:

Start        End      Trend

200712      200712     unknown
200801      200804     UP
200805      200805     SAME
200806      200809     DOWN
200810      200810     UP
200811      200811     DOWN
200812      200812     UP
200903      200903     DOWN
200904      200905     SAME
200906      200907     UP

任何帮助都会非常有用;感谢

1 个答案:

答案 0 :(得分:1)

花了我一些时间(和几个小时),但我想我有你想要的东西:

DECLARE @Sales AS TABLE (mnth datetime, qty int)

INSERT INTO @Sales
SELECT '2016-01-01', 10 UNION ALL 
SELECT '2016-02-01', 20 UNION ALL 
SELECT '2016-03-01', 30 UNION ALL 
SELECT '2016-04-01', 40 UNION ALL 
SELECT '2016-05-01', 40 UNION ALL 
SELECT '2016-06-01', 30 UNION ALL 
SELECT '2016-07-01', 20 UNION ALL 
SELECT '2016-08-01', 30 UNION ALL 
SELECT '2016-09-01', 40 UNION ALL 
SELECT '2016-10-01', 45 UNION ALL 
SELECT '2016-11-01', 50

;WITH etape1 AS (
    SELECT ROW_NUMBER() OVER(ORDER BY mnth) AS id, * FROM @Sales
)
, etape2 AS (
    SELECT id, lag(mnth) OVER (ORDER BY id) AS START, mnth AS FINISH, CASE WHEN qty - LAG(qty) OVER (ORDER BY id) < 0 THEN -1 WHEN qty - LAG(qty) OVER (ORDER BY id) > 0 THEN 1 ELSE 0 END AS TREND
    FROM etape1
)
, etape3 AS (
    SELECT id, START, FINISH, TREND, lag(TREND) OVER (ORDER BY id) AS PrevTrend
    FROM etape2
) 
, etape4 AS (
    SELECT id, START, FINISH, TREND, SUM(CASE WHEN TREND = PREVTREND THEN 0 ELSE 1 END) OVER (ORDER BY id ROWS UNBOUNDED PRECEDING) AS Change
    FROM etape3
)
SELECT MIN(START) AS START, MAX(FINISH) AS FINISH, CASE WHEN MIN(TREND) IS NULL THEN 'Unknown' WHEN MIN(TREND) < 0 THEN 'Down' WHEN MIN(TREND) > 0 THEN 'Up' WHEN MIN(Start) is NULL THEN 'Unknown' ELSE 'Same' END AS TREND
FROM etape4
GROUP BY Change
ORDER BY START

结果是:

START       FINISH      TREND
NULL        2016-01-01  Unknown
2016-01-01  2016-04-01  Up
2016-04-01  2016-05-01  Same
2016-05-01  2016-07-01  Down
2016-07-01  2016-11-01  Up