SQL:4点上下交替

时间:2018-02-26 15:15:11

标签: sql sql-server sql-server-2008

我正在尝试编写一个查询,用于标识上下交替的4个连续点。我在下面列出了测试数据,预期结果和我的查询。我的查询没有产生正确的结果,我无法理解为什么。任何帮助将不胜感激。

E.g。 Wk 5有4个点上下交替(wk,2,3,4,5)。

;CREATE TABLE #B (Wk INT, Rate DECIMAL(18,4))
;INSERT INTO #B (Wk, Rate) VALUES 
(1, 0.0),   
(2, 0.1),
(3, 0.2),   
(4, 0.1),   
(5, 0.3),--1    
(6, 0.2),--1    
(7, 0.1),   
(8, 0.3),   
(9, 0.2),--1    
(10,0.1)

;WITH StartingWk AS (
    SELECT Wk CurrentWk, Rate CurrentRate
    FROM #B
), A AS (
    SELECT b1.Wk, b1.Rate,CASE WHEN b1.Rate > B2.Rate THEN 1 ELSE 0 END AS inc
    FROM #B b1
    LEFT JOIN #B b2 ON b1.Wk = b2.Wk+1
), B AS (
    SELECT StartingWk.CurrentWk, A.*
    FROM StartingWk
    LEFT JOIN A ON A.Wk >= StartingWk.CurrentWk aND A.Wk < StartingWk.CurrentWk+4
), C AS (
    SELECT DISTINCT B1.CurrentWk, B1.Wk, CASE WHEN B1.inc != ISNULL(b2.inc,1) THEN 1 ELSE 0 END AS YN 
    FROM B B1 
    LEFT JOIN B B2 ON B1.Wk = B2.Wk-1 AND B1.inc != ISNULL(b2.inc,1) 
)
SELECT C1.CurrentWk, MAX(C1.Wk) EndingWk, SUM(YN)YN
FROM C C1
GROUP BY C1.CurrentWk
HAVING SUM(YN) = 4

预期结果:

WK |Rate|YN|
------------
|1 |0.0 |0 |
|2 |0.1 |0 |
|3 |0.2 |0 | 
|4 |0.1 |0 |
|5 |0.3 |1 | 
|6 |0.2 |1 | 
|7 |0.1 |0 | 
|8 |0.3 |0 | 
|9 |0.2 |1 | 
|10|0.4 |0 | 

1 个答案:

答案 0 :(得分:1)

对于SQL 2008 recursive CTE可能是更好的选择。查询将每行与前面的3行进行比较,并根据Rate的变化形成结果字符串(1 - 增加,-1 - 减少,0没有变化)。上下交替的字符串应该看起来像1-11-11-1

with cte as (
    select
        *, rn = row_number() over (order by wk)
    from
        #B
)
, rcte as (
    select *, 1 step, res = cast('' as varchar(200))
    from cte
    union all
    select
        a.Wk, b.Rate, b.rn, a.step + 1
        , cast(a.res + case when b.Rate > a.Rate then '1' when b.Rate < a.Rate then '-1' else '0' end as varchar(200))
    from
        rcte a
        join cte b on a.rn - 1 = b.rn
    where
        a.step < 4
)
select 
    top 1 with ties Wk, Rate
    , YN = case when res in ('1-11', '-11-1') then 1 else 0 end
from rcte
order by row_number() over (partition by wk order by step desc)

输出

Wk  Rate    YN
--------------
1   0.0000  0
2   0.0000  0
3   0.0000  0
4   0.0000  0
5   0.1000  1
6   0.2000  1
7   0.1000  0
8   0.3000  0
9   0.2000  1
10  0.1000  0