使用带有年和月(时间段)的 SQL Server 窗口函数

问题描述 投票:0回答:1

请考虑这个脚本:

Declare @tbl Table
(
    F1    int,
    F2    int,
    Year  int,
    Month tinyint
)

Insert into @tbl 
values
(10, 1, 2020, 1),
(10, 1, 2020, 2),
(10, 1, 2020, 3),
(10, 1, 2020, 4),
(10, 2, 2020, 5),
(10, 1, 2020, 6),
(10, 1, 2020, 7),
(11, 1, 2020, 1),
(11, 1, 2020, 2),
(11, 2, 2020, 3),
(11, 2, 2020, 4),
(11, 1, 2020, 5),
(12, 1, 2020, 1),
(12, 1, 2020, 2),
(12, 1, 2020, 3),
(12, 1, 2020, 4)

我写了这个查询:

Select 
    F1, F2, year, month,
    Row_number() over (partition by F1, F2 order by year, month) as rownumber,
    Rank() over (partition by F1, F2 order by year, month) as rnk
From 
    @tbl
Order by 
    f1, f2, year, month

此查询返回此结果集:

F1.     F2.      Year.     Month.     Rownumber.     Rnk
------------------------------------------------‐-------------
10      1        2020         1           1           1
10      1        2020         2           2           2
10      1        2020         3           3           3
10      1        2020         4           4           4
10      1        2020         6           5           5
10      1        2020         7           6           6
10      2        2020         5           1           1
11      1        2020         1           1           1
11      1        2020         2           2           2
11      1        2020         5           3           3
11      2        2020         3           1           1
11      2        2020         4           2           2
12      1        2020         1           1           1
12      1        2020         2           2           2
12      1        2020         3           3           3
12      1        2020         4           4           4

但我想要这个结果:

F1.     F2.      Year.     Month.     Sequence.   
------------------------------------------------
10      1        2020         1           1     
10      1        2020         2           2      
10      1        2020         3           3        
10      1        2020         4           4      
10      2        2020         5           1      
10      1        2020         6           1       
10      1        2020         7           2       
11      1        2020         1           1       
11      1        2020         2           2        
11      2        2020         3           1       
11      2        2020         4           2          
11      1        2020         5           1        
12      1        2020         1           1         
12      1        2020         2           2        
12      1        2020         3           3        
12      1        2020         4           4        

怎样才能达到我想要的结果?谢谢

sql sql-server window-functions
1个回答
0
投票

这基本上是变相的差距和孤岛问题。 这里,每个“岛”是属于同一个

F1
块的一组记录,其中
F2
值在年份和月份中没有按顺序变化。 我们可以生成一个伪组来跟踪这些记录,然后使用
ROW_NUMBER()
来生成最终的序列值。 请注意,当
F2
块结束或
F2
值发生变化时,此伪组值重置为 1。

WITH cte AS (
    SELECT *, CASE WHEN LAG(F2) OVER (PARTITION BY F1 ORDER BY Year, Month) != F2 THEN 1 ELSE 0 END AS flag
    FROM @tbl
),
cte2 AS (
    SELECT *, SUM(flag) OVER (PARTITION BY F1 ORDER BY Year, Month) grp
    FROM cte
),
cte3 AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY F1 ORDER BY Year, Month) rn1,
              ROW_NUMBER() OVER (PARTITION BY F1, grp ORDER BY Year, Month) rn2
    FROM cte2
)

SELECT F1, F2, Year, Month,
       ROW_NUMBER() OVER (PARTITION BY F1, rn1 - rn2 ORDER BY Year, Month) AS seq
FROM cte3
ORDER BY F1, Year, Month;
© www.soinside.com 2019 - 2024. All rights reserved.