如果序列没有破坏,则获取多行的总时间间隔
我有 Work
和 Person
表(这些只是理解问题的示例)。
结构
Work
表
id INTEGER
person_id INTEGER
dt_from DATETIME
dt_to DATETIME
Person
表
person_id INTEGER
name VARCHAR(50)
数据
Work
表
id | person_id | dt_from | dt_to
-------------------------------------------------
1 | 1 | 2011-01-01 | 2011-02-02
2 | 1 | 2011-02-02 | 2011-04-04
3 | 1 | 2011-06-06 | 2011-09-09
4 | 2 | 2011-01-01 | 2011-02-02
5 | 2 | 2011-02-02 | 2011-03-03
....etc.
Person
表
仅包含人员 ID 的人员姓名
预期输出
Person 1 : 2011-01-01 - 2011-04-04
Person 1 : 2011-06-06 - 2011-09-09
Person 2 : 2011-01-01 - 2011-03-03
间隔必须在顺序。它不能在中间的某个地方被破坏。这就是为什么第一个人有两个间隔。
如果它改变了某些东西,我正在使用 postgres。你有什么想法吗? 我想在一个查询中完成它,但如果没有这样的解决方案,我将在 php 中进行一些间隔合并。
I have Work
and Person
tables (these are just examples to understand problem).
Structure
Work
table
id INTEGER
person_id INTEGER
dt_from DATETIME
dt_to DATETIME
Person
table
person_id INTEGER
name VARCHAR(50)
Data
Work
table
id | person_id | dt_from | dt_to
-------------------------------------------------
1 | 1 | 2011-01-01 | 2011-02-02
2 | 1 | 2011-02-02 | 2011-04-04
3 | 1 | 2011-06-06 | 2011-09-09
4 | 2 | 2011-01-01 | 2011-02-02
5 | 2 | 2011-02-02 | 2011-03-03
....etc.
Person
table
Just person names with person id
Expected output
Person 1 : 2011-01-01 - 2011-04-04
Person 1 : 2011-06-06 - 2011-09-09
Person 2 : 2011-01-01 - 2011-03-03
Interval must be in sequence. It cannot be broken somewhere in middle. Thats why Person 1 have two intervals.
I'm using postgres if it changes something. Have you any thougths?
I wanted do it in one query, but if there is no such solution i will do some interval merge in php.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
也许有一种方法可以在一个 SQL 选择中做到这一点,但我没有想到。不过,我设法用一个存储函数来做到这一点。这是我为测试所做的:
然后
返回了这个结果:
我认为这就是您所追求的。
There may be a way to do this in one SQL select, but it escapes me. I managed to do it with one stored function though. Here's what I did for my testing:
Then
returned this result:
which is, I think, what you're after.
您可以尝试 postgres 的 WITH RECURSIVE 构造。 (毕竟,链表是一种树)获得正确的边界条件将是一个问题,但至少它可以解决问题而不需要循环。
更新:添加了代码。 RECURSIVE 的问题是您只能指定“尾部”边界条件。要指定“head”条件,您需要将其包装到视图中。
-- 现在生成一些有间隙的数据
生成的查询计划看起来很完美:
You could try postgres's WITH RECURSIVE construct. (after all, a linked list is a kind of tree) Getting the boundary conditions right will be a problem, but at least it would solve the problem without the need for loops.
UPDATE: Added code. The problem with RECURSIVE is that you can only specify only the "tail" boundary condition. To specify the "head" condition, you need to wrap it into a view.
-- now generate some data with gaps
The resulting query plan looks perfect: