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 ROW
到 SUM
组更改。
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
我的目标是获得这样的记录集
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 ROW
到 SUM
组更改。
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