递归地将日期列表分组
Posted
技术标签:
【中文标题】递归地将日期列表分组【英文标题】:Recursively dividing a list of dates into groups 【发布时间】:2020-08-10 15:00:34 【问题描述】:我有一个如下的开始日期列表 -
start dates sorted in descending order
开始日期始终按降序排列。 我正在寻找可以提供以下输出的 postgresql 查询- start dates with groups
基本上,我试图从给定列表中创建日期组,以便组中的每个日期都在相应组顶部日期的 61 天内。 例如 - 在输出中,
组 1 有前 4 条记录,因为所有 4 个开始日期都在 61 以内 记录天数2. 第 2 组仅包含记录号。 6 因为超过 61 天 远离记录号。 2. 组 3 包含行号。 7 和 8,因为他们超过 61 离记录号还有几天。 6. 但在 61 天之内附:我是 postgresql 和 *** 的新手。 任何指针都会有所帮助
【问题讨论】:
样本数据最好显示为formatted text。请参阅here,了解有关如何创建漂亮表格的一些提示。 会牢记这一点。感谢您的建议 【参考方案1】:您的示例数据与您的示例输出不匹配。
您在示例输出中的计算是错误的,因为这是倒数,3 月和 10 月都有 31 天。
要正确递归,您需要使用 dense_rank()
分配行号:
with recursive num as (
select row_number() over (order by start_date desc) as rn,
start_date
from dateslist
),
然后,您创建组并通过在递归时将锚值向前传递来找到差距。由于您拥有start_date
信息,您可以同时计算组内的偏移量:
find_gaps as (
select rn as anchor, start_date as anchor_date, rn, start_date, 0 as group_offset
from num
where rn = 1
union all
select case
when f.anchor_date - n.start_date > 61 then n.rn
else f.anchor
end,
case
when f.anchor_date - n.start_date > 61 then n.start_date
else f.anchor_date
end,
n.rn, n.start_date,
case
when f.anchor_date - n.start_date > 61 then n.start_date
else f.anchor_date
end - n.start_date
from find_gaps f
join num n on n.rn = f.rn + 1
)
最后的查询选择你想要输出的列并应用一个组号。
select start_date,
dense_rank() over (order by anchor) as group_number,
group_offset
from find_gaps
order by start_date desc;
Working Fiddle Demo
【讨论】:
感谢您的解决方案。这正是我所需要的 我是递归查询的新手。你能帮忙解释一下吗。我尝试使用以下日期进行测试('09-02-2018 00:00')、('07-05-2021 00:00')、('07-05-2021 00:00')、('07- 06-2021 00:00'), ('07-24-2019 00:00') - 但在输出中获得了两条额外的记录 @AnindyaMukherjea 这种重复是由于2021-07-05
在您的数据中输入了两次。如果将 union all
更改为 union
,这将导致递归 CTE 消除重复项。请在此处查看更新的小提琴:db-fiddle.com/f/6opXrtd9muc9RvZCj938NS/2
现在它从输出中删除了一行。输入有 12 行,但输出有 11 行。似乎可以将输出视为字典。保持联合和左外连接似乎可以解决问题 - db-fiddle.com/f/6opXrtd9muc9RvZCj938NS/3
@AnindyaMukherjea 对不起。我给了你一个糟糕的解决方案。保留union all
,但在顶部cte num
中,将dense_rank()
更改为row_number()
。我会更新 DB-fiddle,但看起来该站点现在无法正常工作。我会在上面更新我的答案。以上是关于递归地将日期列表分组的主要内容,如果未能解决你的问题,请参考以下文章