Microsoft SQL 服务器连胜计数器
Microsoft SQL Server Streak Counter
我有以下格式的数据:
ID
Period
Date
1
1
2020-09-05
1
2
2020-10-01
1
3
2020-10-30
2
2
2020-10-01
2
4
2020-12-05
2
6
2021-02-05
3
1
2020-09-05
我想按 ID 和句点计算连续分组。每个组的第一个日期实例应从 1 开始,如果下一行中的日期距第一行不到 30 天,则连胜计数器 +1。如果下一行是 30 天或更长时间,这应该重置为 1。
这是我想要的输出:
ID
Period
Date
Counter
1
1
2020-09-05
1
1
2
2020-10-01
2
1
3
2020-10-30
3
2
2
2020-10-01
1
2
4
2020-12-05
1
2
6
2021-02-05
1
3
1
2020-09-05
1
我完全坚持这一点 - 任何帮助将不胜感激。我正在使用 Microsoft SQL 服务器。
编辑:实际使用 Microsoft SQL 服务器
从 Oracle 12c 开始,您可以使用 MATCH_RECOGNIZE
执行 row-by-row 比较:
SELECT id,
period,
"DATE",
counter
FROM table_name
MATCH_RECOGNIZE(
PARTITION BY id
ORDER BY "DATE"
MEASURES
COUNT(*) AS counter
ALL ROWS PER MATCH
PATTERN (any_date streak_date*)
DEFINE
streak_date AS "DATE" <= PREV("DATE") + INTERVAL '30' DAY
-- AND PREV(period) < period
)
其中,对于示例数据:
CREATE TABLE table_name (ID, Period, "DATE") AS
SELECT 1, 1, DATE '2020-09-05' FROM DUAL UNION ALL
SELECT 1, 2, DATE '2020-10-01' FROM DUAL UNION ALL
SELECT 1, 3, DATE '2020-10-30' FROM DUAL UNION ALL
SELECT 2, 2, DATE '2020-10-01' FROM DUAL UNION ALL
SELECT 2, 4, DATE '2020-12-05' FROM DUAL UNION ALL
SELECT 2, 6, DATE '2021-02-05' FROM DUAL UNION ALL
SELECT 3, 1, DATE '2020-09-05' FROM DUAL
注意:DATE
是保留字,将其用作列名是不好的做法。
输出:
ID
PERIOD
DATE
COUNTER
1
1
2020-09-05 00:00:00
1
1
2
2020-10-01 00:00:00
2
1
3
2020-10-30 00:00:00
3
2
2
2020-10-01 00:00:00
1
2
4
2020-12-05 00:00:00
1
2
6
2021-02-05 00:00:00
1
3
1
2020-09-05 00:00:00
1
db<>fiddle here
我有以下格式的数据:
ID | Period | Date |
---|---|---|
1 | 1 | 2020-09-05 |
1 | 2 | 2020-10-01 |
1 | 3 | 2020-10-30 |
2 | 2 | 2020-10-01 |
2 | 4 | 2020-12-05 |
2 | 6 | 2021-02-05 |
3 | 1 | 2020-09-05 |
我想按 ID 和句点计算连续分组。每个组的第一个日期实例应从 1 开始,如果下一行中的日期距第一行不到 30 天,则连胜计数器 +1。如果下一行是 30 天或更长时间,这应该重置为 1。
这是我想要的输出:
ID | Period | Date | Counter |
---|---|---|---|
1 | 1 | 2020-09-05 | 1 |
1 | 2 | 2020-10-01 | 2 |
1 | 3 | 2020-10-30 | 3 |
2 | 2 | 2020-10-01 | 1 |
2 | 4 | 2020-12-05 | 1 |
2 | 6 | 2021-02-05 | 1 |
3 | 1 | 2020-09-05 | 1 |
我完全坚持这一点 - 任何帮助将不胜感激。我正在使用 Microsoft SQL 服务器。
编辑:实际使用 Microsoft SQL 服务器
从 Oracle 12c 开始,您可以使用 MATCH_RECOGNIZE
执行 row-by-row 比较:
SELECT id,
period,
"DATE",
counter
FROM table_name
MATCH_RECOGNIZE(
PARTITION BY id
ORDER BY "DATE"
MEASURES
COUNT(*) AS counter
ALL ROWS PER MATCH
PATTERN (any_date streak_date*)
DEFINE
streak_date AS "DATE" <= PREV("DATE") + INTERVAL '30' DAY
-- AND PREV(period) < period
)
其中,对于示例数据:
CREATE TABLE table_name (ID, Period, "DATE") AS
SELECT 1, 1, DATE '2020-09-05' FROM DUAL UNION ALL
SELECT 1, 2, DATE '2020-10-01' FROM DUAL UNION ALL
SELECT 1, 3, DATE '2020-10-30' FROM DUAL UNION ALL
SELECT 2, 2, DATE '2020-10-01' FROM DUAL UNION ALL
SELECT 2, 4, DATE '2020-12-05' FROM DUAL UNION ALL
SELECT 2, 6, DATE '2021-02-05' FROM DUAL UNION ALL
SELECT 3, 1, DATE '2020-09-05' FROM DUAL
注意:DATE
是保留字,将其用作列名是不好的做法。
输出:
ID PERIOD DATE COUNTER 1 1 2020-09-05 00:00:00 1 1 2 2020-10-01 00:00:00 2 1 3 2020-10-30 00:00:00 3 2 2 2020-10-01 00:00:00 1 2 4 2020-12-05 00:00:00 1 2 6 2021-02-05 00:00:00 1 3 1 2020-09-05 00:00:00 1
db<>fiddle here