请考虑这个脚本:
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
怎样才能达到我想要的结果?谢谢
这基本上是变相的差距和孤岛问题。 这里,每个“岛”是属于同一个
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;