从 SQL 到 SPL:count date ranges per year

数据库表 example 的 x 字段是 id,ts 字段是时间区间。

x

ts

1

["2024-12-27 00:00:00","2025-02-01 00:00:00"]

2

["2025-05-01 00:00:00","2025-05-05 00:00:00"]

3

["2025-05-08 00:00:00","2025-05-20 00:00:00"]

现在要统计出每个 id 的时间区间里含有哪些年份,每年包含多少天。

x

extract

count

1

2024

5

1

2025

32

2

2025

5

3

2025

13

SQL

WITH RECURSIVE days as (
  SELECT x, LOWER(ts) as t FROM example 
    UNION ALL
  SELECT x, t+'1 day' FROM days 
  where t < (SELECT UPPER(ts) FROM example where x=days.x)
  )
SELECT x, extract(year from t), count(*)
FROM days
GROUP BY x,extract(year from t)
ORDER BY x,extract(year from t)

一般数据库没有时间区间相关的数据类型,拆解数据会很麻烦,postgresql 有 tsrange、daterange 类型,代码相对好写,但也要用递归子查询造出日期序列,结构复杂不易理解。SPL 可以直接生成日期序列:https://try.esproc.com/splx?3uS


 A

1

$select * from example.txt

2

=A1.news(periods(date(ts(1)),date(ts(2))); x,~:t)

3

=A2.groups(x, year(t):extract; count(1):count)

A1:加载数据。[…] 会被解析为序列。

A2:用每条记录的 ts 字段生成日期序列,再将序列的成员展开,与本条记录的 x 字段组成新二维表。函数 periods 根据起止日期生成序列,(1) 表示序列的第 1 个成员。

问题来源:https://stackoverflow.com/questions/78171203/is-it-possible-with-sql-to-count-all-dateranges-per-year