说在MonetDB(特别是"MonetDBLite"R包中的嵌入式版本(中,我有一个表;事件";包含实体ID代码和事件开始和结束日期,格式为:
| id | start_date | end_date |
| 1 | 2010-01-01 | 2010-03-30 |
| 1 | 2010-04-01 | 2010-06-30 |
| 2 | 2018-04-01 | 2018-06-30 |
| ... | ... | ... |
该表包含约8000万行事件,可归因于约250万个唯一实体(ID值(。日期似乎与日历季度很好地对齐,但我还没有彻底检查过,所以我认为它们可能是任意的。然而,我至少有理智地检查了它们的end_date>start_date。
我想制作一张桌子";无事件_ qtrs";列出ID没有事件记录的日历季度,例如:
| id | last_doq |
| 1 | 2010-09-30 |
| 1 | 2010-12-31 |
| ... | ... |
| 1 | 2018-06-30 |
| 2 | 2010-03-30 |
| ... | ... |
(doq=季度日(
如果一个事件的范围跨越了该季度的任何一天(包括第一天和最后一天(,那么我希望它能算作发生在该季度。
为了帮助解决这个问题,我制作了一个";日历表";;"四分之一表";qtrs";,覆盖了";事件";,和格式:
| first_doq | last_doq |
| 2010-01-01 | 2010-03-30 |
| 2010-04-01 | 2010-06-30 |
| ... | ... |
并尝试使用类似的非等合并:
create table nonevents
as select
id,
last_doq
from
events
full outer join
qtrs
on
start_date > last_doq or
end_date < first_doq
group by
id,
last_doq
但这是a(效率极低,b(肯定是错误的,因为大多数ID都被列为对所有方面都不重要。
我如何制作表格"无事件_ qtrs";我描述过,其中包含每个ID都没有事件的季度列表
如果它是相关的,那么最终的用例是计算非事件的运行,以查看事件分析和预测的时间。感觉需要进行行程编码。如果有比我上面描述的更直接的方法,那么我会洗耳恭听。我开始关注非事件运行的唯一原因是试图限制交叉乘积的大小。我也考虑过生产类似的产品:
| id | last_doq | event |
| 1 | 2010-01-31 | 1 |
| ... | ... | ... |
| 1 | 2018-06-30 | 0 |
| ... | ... | ... |
但是,尽管这更有用,但由于所涉及的数据的大小,这可能是不可行的。一种广泛的格式:
| id | 2010-01-31 | ... | 2018-06-30 |
| 1 | 1 | ... | 0 |
| 2 | 0 | ... | 1 |
| ... | ... | ... | ... |
也很方便,但由于MonetDB是列存储,我不确定这是否更有效。
让我假设您有一个季度表,其中包含季度的开始日期和结束日期。如果你想要不存在的季度,你真的需要这个。毕竟,你想在时间上倒退或向前走多远?
然后,您可以生成所有id/季度组合,并过滤掉存在的组合:
select i.id, q.*
from (select distinct id from events) i cross join
quarters q left join
events e
on e.id = i.id and
e.start_date <= q.quarter_end and
e.end_date >= q.quarter_start
where e.id is null;