2017-09-11 85 views
1

我的目标,以获得一个记录集这样T-SQL进步编号分区

date flag number 
01  0  1 
02  0  1 
03  1  2 
04  1  2 
05  1  2 
06  0  3 
07  1  4 
08  1  4 

我从“日期”,只有“标志”设置记录开始。我正在尝试使用T-SQL排名和分区函数来计算“数字”列。

一个正常的排名会得到这样的结果:

date flag number 
    01  0  1 
    02  0  1 
    03  1  2 
    04  1  2 
    05  1  2 
    06  0  1 
    07  1  2 
    08  1  2 

什么建议吗?

回答

1

你可以试试这个:

DECLARE @DataSource TABLE 
(
    [date] CHAR(2) 
    ,[flag] BIT 
); 

INSERT INTO @DataSource ([date], [flag]) 
VALUES ('01', 0) 
     ,('02', 0) 
     ,('03', 1) 
     ,('04', 1) 
     ,('05', 1) 
     ,('06', 0) 
     ,('07', 1) 
     ,('08', 1); 

WITH DataSource ([date], [flag], [number]) AS 
(
    SELECT [date] 
      ,[flag] 
      ,IIF(LAG([flag], 1, NULL) OVER (ORDER BY [date]) = [flag], 0, 1) 
    FROM @DataSource 
) 
SELECT [date] 
     ,[flag] 
     ,SUM([number]) OVER (ORDER BY [date] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS [number] 
FROM DataSource 
ORDER BY [date], [flag]; 

enter image description here

的想法是要检查时,组变为使用LAG功能:

IIF(LAG([flag], 1, NULL) OVER (ORDER BY [date]) = [flag], 0, 1) 

然后,使用BETWEEN UNBOUNDED PRECEDING AND CURRENT ROWSUM组变化。

1

Ĵ,

SQL Server 2012的具有多个例如SQL Lead()和SQL滞后新的功能()函数。您可以使用SQL Server Lag() function为您的要求

这里的解决方案是我的解决方案

with cte as (
select 
    date, flag, 
    LAG(flag, 1, NULL) OVER (ORDER BY date) AS preVal, 
    case when flag = ISNULL((LAG(flag, 1, NULL) OVER (ORDER BY date)), flag) then 0 else 1 end as i 
from recordset 
) 
select 
    cte.date, 
    cte.flag, 
    sum(cte2.i)+1 r 
from cte 
inner join cte as cte2 on cte.date >= cte2.date 
group by cte.date, cte.flag 
order by cte.date 
+0

您的解决方案是好的,工作,谢谢您。 我更喜欢gotqn的一个,因为它更线性可读,他使用OVER BY命令的rows/range选项子句。 –

+1

没问题:)我也学到了“BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW”选项,最好继续 – Eralper

0

你可以填充它在光标这样的:

DECLARE @Table TABLE (
[Date] [nvarchar](50) NULL, 
[flag] [int] NULL, 
[Number] [int] NULL 
) 

DECLARE @Date nvarchar(50) 
DECLARE @flag int 
DECLARE @number int 
DECLARE @flagnumber int 
DECLARE @flagincrement int 

DECLARE MyCursor CURSOR FOR 
SELECT [Date],FLag 
FROM [LegOgSpass].[dbo].[testflag] 
Order by [Date] 

OPEN MyCursor 
FETCH NEXT FROM MyCursor 
INTO @Date,@flag 

IF (@@FETCH_STATUS>=0) 
BEGIN 

SET @number = 1 
SET @flagincrement = @flag 

INSERT INTO @Table ([Date],[Flag],[Number]) 
VALUES(@Date,@flag,@number) 

FETCH NEXT FROM MyCursor INTO @Date,@flag 
END 
WHILE (@@FETCH_STATUS<>-1) 
BEGIN 
IF (@@FETCH_STATUS<>-2) 
IF @flagincrement = @flag 
SET @number = @number 

ELSE 
SET @number = @number+1 
SET @flagincrement = @flag 

INSERT INTO @Table ([Date],[Flag],[Number]) 
VALUES(@Date,@flag,@number) 
FETCH NEXT FROM MyCursor INTO @Date,@flag 
END 

CLOSE MyCursor 
DEALLOCATE MyCursor 

SELECT * FROM @Table 
+0

您的解决方案是可以接受的,谢谢,但我试图避免游标和迭代:我正在更新问题。 –

+0

我知道,我只是想举一个例子 - 很高兴你能使用它:) – plaidDK