如何在我的SQL Server表中找到n个连续值(where regStatus = 0)假设我给3,则必须返回3个连续记录

时间:2016-04-01 04:34:41

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

为了您的方便,我正在显示我的数据和所需的输出。

DECLARE @TResults TABLE 
            (
                keyId INT,          
                peopleId    INT,                
                sesnId      INt,
                sesName     nvarchar(max),
                sesOrder    int,
                regStatus   int
            )  
INSERT @TResults  
SELECT  1,      169199,     166,    '1 Mar, 2016',  1,  0 UNION ALL  
SELECT  2,      169199,     167,    '2 Mar, 2016',  2,  1  UNION ALL  
SELECT  3,      169199,     168,    '3 Mar, 2016',  3,  1  UNION ALL  
SELECT  4,      169199,     169,    '4 Mar, 2016',  4,  0  UNION ALL  
SELECT  5,      169199,     170,    '5 Mar, 2016',  5,  0  UNION ALL  
SELECT  6,      169199,     231,    '6 Mar, 2016',  6,  0  UNION ALL  
SELECT  7,      169199,     232,    '7 Mar, 2016',  7,  0  UNION ALL  
SELECT  8,      297067,     166,    '1 Mar, 2016',  1,  0 UNION ALL  
SELECT  9,      297067,     167,    '2 Mar, 2016',  2,  1 UNION ALL  
SELECT  10,     297067,     168,    '3 Mar, 2016',  3,  0 UNION ALL  
SELECT  11,     297067,     169,    '4 Mar, 2016',  4,  0 UNION ALL  
SELECT  12,     297067,     170,    '5 Mar, 2016',  5,  1 UNION ALL  
SELECT  13,     297067,     231,    '6 Mar, 2016',  6,  0 UNION ALL  
SELECT  14,     297067,     232,    '7 Mar, 2016',  7,  0 UNION ALL  
SELECT  15,     338143,     166,    '1 Mar, 2016',  1,  1 UNION ALL  
SELECT  16,     338143,     167,    '2 Mar, 2016',  2,  1 UNION ALL  
SELECT  17,     338143,     168,    '3 Mar, 2016',  3,  0 UNION ALL  
SELECT  18,     338143,     169,    '4 Mar, 2016',  4,  1 UNION ALL  
SELECT  19,     338143,     170,    '5 Mar, 2016',  5,  0 UNION ALL  
SELECT  20,     338143,     231,    '6 Mar, 2016',  6,  0 UNION ALL  
SELECT  21,     338143,     232,    '7 Mar, 2016',  7,  0  

SELECT * FROM @TResults  

上述命令的输出将如下

keyId   peopleId    sesnId  sesName      sesOrder   **regStatus**  
1       169199      166     1 Mar, 2016  1             0  
2       169199      167     2 Mar, 2016  2             1  
3       169199      168     3 Mar, 2016  3             1  
4       169199      169     4 Mar, 2016  4             0  
5       169199      170     5 Mar, 2016  5             0  
6       169199      231     6 Mar, 2016  6             0  
7       169199      232     7 Mar, 2016  7             0  
8       297067      166     1 Mar, 2016  1             0  
9       297067      167     2 Mar, 2016  2             1  
10      297067      168     3 Mar, 2016 3              0  
11      297067      169     4 Mar, 2016  4             0  
12      297067      170     5 Mar, 2016  5             1  
13      297067      231     6 Mar, 2016  6             0  
14      297067      232     7 Mar, 2016  7             0  
15      338143      166     1 Mar, 2016  1             1  
16      338143      167     2 Mar, 2016  2             1  
17      338143      168     3 Mar, 2016  3             0  
18      338143      169     4 Mar, 2016  4             1  
19      338143      170     5 Mar, 2016  5             0  
20      338143      231     6 Mar, 2016  6             0  
21      338143      232     7 Mar, 2016  7             0  

现在我想要的是,假设如果我给2.它必须从每个empid返回2个连续记录regStatus = 0

离。

keyId   peopleId    sesnId  sesName      sesOrder   **regStatus**  
4       169199      169     4 Mar, 2016  4             0  
5       169199      170     5 Mar, 2016  5             0  
6       169199      231     6 Mar, 2016  6             0  
7       169199      232     7 Mar, 2016  7             0  
10      297067      168     3 Mar, 2016 3              0  
11      297067      169     4 Mar, 2016  4             0  
13      297067      231     6 Mar, 2016  6             0  
14      297067      232     7 Mar, 2016  7             0  
19      338143      170     5 Mar, 2016  5             0  
20      338143      231     6 Mar, 2016  6             0  

请注意

keyId   peopleId    sesnId  sesName      sesOrder   **regStatus**  
4       169199      169     4 Mar, 2016  4             0  
5       169199      170     5 Mar, 2016  5             0  
6       169199      231     6 Mar, 2016  6             0  
7       169199      232     7 Mar, 2016  7             0  

有4条记录。但它们是连续的,我们曾要求连续2次返回记录。

OR

假设我给3.它必须从每个empid返回3个连续记录regStatus = 0

keyId   peopleId    sesnId  sesName      sesOrder   **regStatus**  
4       169199      169     4 Mar, 2016  4             0  
5       169199      170     5 Mar, 2016  5             0  
6       169199      231     6 Mar, 2016  6             0  
19      338143      170     5 Mar, 2016  5             0  
20      338143      231     6 Mar, 2016  6             0  
21     338143       232     7 Mar, 2016  7             0  

假设我给4.它必须从每个empid返回4个连续记录,其中regStatus = 0

keyId   peopleId    sesnId  sesName      sesOrder   **regStatus**
4       169199      169     4 Mar, 2016  4             0  
5       169199      170     5 Mar, 2016  5             0  
6       169199      231     6 Mar, 2016  6             0  
7       169199      232     7 Mar, 2016  7             0  

请帮助我实现这一目标。

1 个答案:

答案 0 :(得分:1)

使用ROW_NUMBER s的差异:

DECLARE @N INT = 2;

WITH Cte AS(
    SELECT *,
        rn = ROW_NUMBER() OVER(PARTITION BY peopleId ORDER BY sesOrder),
        rn2 = ROW_NUMBER() OVER(PARTITION BY peopleId ORDER BY sesOrder)
                - ROW_NUMBER() OVER(PARTITION BY peopleId, regStatus ORDER BY sesOrder)
    FROM @TResults
),
Cte2 AS(
    SELECT *,
        grp = rn - ((ROW_NUMBER() OVER(PARTITION BY peopleId, rn2 ORDER BY sesOrder) - 1) % @N)
    FROM Cte
    WHERE regStatus = 0
),
CteFinal AS(
    SELECT *,
        cnt = COUNT(*) OVER(PARTITION BY peopleId, rn2, grp)
    FROM Cte2
)
SELECT
    keyId, peopleId, sesnId, sesName, sesOrder, regStatus
FROM CteFinal
WHERE cnt = @N

ONLINE DEMO