T-SQL - 聚合(MIN/MAX 日期)考虑时间顺序 - SQL Server 2012
T-SQL - Aggregate (MIN/MAX date) considering chronological sequence - SQL Server 2012
我无法想象如何使用 t-sql.
解决我的问题
- 我需要 table 中的 MIN(ValidFrom) 和 MAX(ValidTo),考虑到时间顺序和数字,具有不同的时间块。
- 普通组将无法工作,因为 num 100 的 MIN(ValidFrom) 和 MAX(ValidTo) 不正确。
- 我无法想象如何使用 t-sql.
中的任何分析或排名函数从此 table 获得预期结果
我需要以下 table 中的最小和最大日期。
ValidFrom
ValidTo
Num
ID Number
2019-06-01
2019-12-31
100
01234567
2020-01-01
2020-03-31
100
01234567
2020-04-01
2020-12-31
100
01234567
2021-01-01
2021-01-31
100
01234567
2021-02-01
2021-03-31
50
01234567
2021-04-01
2021-09-30
50
01234567
2021-10-01
2021-12-31
50
01234567
2022-01-01
2022-04-30
100
01234567
查询的预期结果:
ValidFrom
ValidTo
Num
ID Number
2019-06-01
2021-01-31
100
01234567
2021-02-01
2021-12-31
50
01234567
2022-01-01
2022-04-30
100
01234567
根据2可以计算出排名ROW_NUMBER
。
一旦有了排名,就很容易汇总了。
-- rank via ascending row_number + descending row_number
SELECT
MIN(ValidFrom) AS ValidFrom
, MAX(ValidTo) AS ValidTo
, Num
, [ID Number]
-- , Rnk
FROM
(
SELECT *
, Rnk = ROW_NUMBER() OVER (PARTITION BY [ID Number] ORDER BY ValidFrom ASC, ValidTo ASC)
+ ROW_NUMBER() OVER (PARTITION BY [ID Number], Num ORDER BY ValidFrom DESC, ValidTo DESC)
FROM your_table
) q
GROUP BY [ID Number], Num, Rnk
ORDER BY [ID Number], MIN(ValidFrom)
ValidFrom
ValidTo
Num
ID Number
2019-06-01
2021-01-31
100
1234567
2021-02-01
2021-12-31
50
1234567
2022-01-01
2022-04-30
100
1234567
第二种方法
-- rank via summing flag on change
SELECT
MIN(ValidFrom) AS ValidFrom
, MAX(ValidTo) AS ValidTo
, Num
, [ID Number]
, Rnk
FROM
(
SELECT *
, Rnk = SUM(flag) OVER (PARTITION BY [ID Number] ORDER BY ValidFrom, ValidTo)
FROM
(
SELECT *
, flag = IIF(Num = LAG(Num) OVER (PARTITION BY [ID Number] ORDER BY ValidFrom, ValidTo), 0, 1)
FROM your_table
) q1
) q2
GROUP BY [ID Number], Num, Rnk
ORDER BY [ID Number], MIN(ValidFrom)
演示 db<>fiddle here
我无法想象如何使用 t-sql.
解决我的问题- 我需要 table 中的 MIN(ValidFrom) 和 MAX(ValidTo),考虑到时间顺序和数字,具有不同的时间块。
- 普通组将无法工作,因为 num 100 的 MIN(ValidFrom) 和 MAX(ValidTo) 不正确。
- 我无法想象如何使用 t-sql. 中的任何分析或排名函数从此 table 获得预期结果
我需要以下 table 中的最小和最大日期。
ValidFrom | ValidTo | Num | ID Number |
---|---|---|---|
2019-06-01 | 2019-12-31 | 100 | 01234567 |
2020-01-01 | 2020-03-31 | 100 | 01234567 |
2020-04-01 | 2020-12-31 | 100 | 01234567 |
2021-01-01 | 2021-01-31 | 100 | 01234567 |
2021-02-01 | 2021-03-31 | 50 | 01234567 |
2021-04-01 | 2021-09-30 | 50 | 01234567 |
2021-10-01 | 2021-12-31 | 50 | 01234567 |
2022-01-01 | 2022-04-30 | 100 | 01234567 |
查询的预期结果:
ValidFrom | ValidTo | Num | ID Number |
---|---|---|---|
2019-06-01 | 2021-01-31 | 100 | 01234567 |
2021-02-01 | 2021-12-31 | 50 | 01234567 |
2022-01-01 | 2022-04-30 | 100 | 01234567 |
根据2可以计算出排名ROW_NUMBER
。
一旦有了排名,就很容易汇总了。
-- rank via ascending row_number + descending row_number SELECT MIN(ValidFrom) AS ValidFrom , MAX(ValidTo) AS ValidTo , Num , [ID Number] -- , Rnk FROM ( SELECT * , Rnk = ROW_NUMBER() OVER (PARTITION BY [ID Number] ORDER BY ValidFrom ASC, ValidTo ASC) + ROW_NUMBER() OVER (PARTITION BY [ID Number], Num ORDER BY ValidFrom DESC, ValidTo DESC) FROM your_table ) q GROUP BY [ID Number], Num, Rnk ORDER BY [ID Number], MIN(ValidFrom)
ValidFrom | ValidTo | Num | ID Number |
---|---|---|---|
2019-06-01 | 2021-01-31 | 100 | 1234567 |
2021-02-01 | 2021-12-31 | 50 | 1234567 |
2022-01-01 | 2022-04-30 | 100 | 1234567 |
第二种方法
-- rank via summing flag on change SELECT MIN(ValidFrom) AS ValidFrom , MAX(ValidTo) AS ValidTo , Num , [ID Number] , Rnk FROM ( SELECT * , Rnk = SUM(flag) OVER (PARTITION BY [ID Number] ORDER BY ValidFrom, ValidTo) FROM ( SELECT * , flag = IIF(Num = LAG(Num) OVER (PARTITION BY [ID Number] ORDER BY ValidFrom, ValidTo), 0, 1) FROM your_table ) q1 ) q2 GROUP BY [ID Number], Num, Rnk ORDER BY [ID Number], MIN(ValidFrom)
演示 db<>fiddle here