T-SQL 递进编号分区

T-SQL progressive numbering partitions

我的目标是获得这样的记录集

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

我只从 "date" 和 "flag" 的记录集开始。我正在尝试使用 T-SQL 排名和分区函数来计算 "number" 列。

正常排名会给出这样的结果:

 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

有什么建议吗?

你可以试试这个:

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];

想法是使用 LAG 函数检查何时更改组:

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

然后,使用 BETWEEN UNBOUNDED PRECEDING AND CURRENT ROWSUM 组更改。

j,

SQL Server 2012 有许多新功能,例如 SQL Lead() and SQL Lag() functions. You can use the 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

您可以像这样在游标中填充它:

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