我有一个名为tb_records
的表,该表记录了发生的情况。样本值为:
id from to
1 01:00:00 01:00:03
2 01:00:05 01:00:07
3 01:00:50 01:00:51
我想做的是在PostgreSQL中生成第二个序列。因此结果将是
id from to time
1 01:00:00 01:00:03 01:00:00
1 01:00:00 01:00:03 01:00:01
1 01:00:00 01:00:03 01:00:02
1 01:00:00 01:00:03 01:00:03
2 01:00:05 01:00:07 01:00:05
2 01:00:05 01:00:07 01:00:06
2 01:00:05 01:00:07 01:00:07
3 01:00:50 01:00:51 01:00:50
3 01:00:50 01:00:51 01:00:51
通常,在Python或R中,我会选择 basic 算法(不使用任何库或程序包):
id
(diff
)的时间差,以秒为单位diff
time
的列from
id
和每一行,将列time
增加一秒钟由于我习惯于按顺序创建这些步骤,因此我对如何在SQL中执行操作感到困惑。
答案 0 :(得分:2)
select id, "from", "to",
generate_series(('2000-01-01 '||"from")::timestamp, ('2000-01-01 '||"to")::timestamp, '1 second'::interval)::time as res
from tb_records
order by id, res
generate_series()
不适用于time
类型,因此我将time
转换为timestamp
,然后从生成的结果中提取time
部分。
答案 1 :(得分:1)
使用日历表并将其加入。 (我将列重命名;“ to”,“ from”和“ time”在SQL中都是保留字)
df1 <- data.frame(Date = as.Date(c("2013-11-01", "2014-02-01", "2014-05-01", "2014-08-01", "2014-11-01", "2015-02-01", "2015-05-01", "2015-08-01", "2015-11-01", "2016-02-01", "2016-05-01", "2016-08-01", "2016-11-01", "2017-02-01", "2017-05-01", "2017-08-01", "2017-11-01", "2018-02-01", "2018-05-01", "2018-08-01")),
Dividend = c(0.08, 0.10, 0.10, 0.10, 0.10, 0.11, 0.00, 0.11, 0.11, 0.13, 0.13, 0.13, 0.13, 0.14, 0.14, 0.00, 0.16, 0.15, 0.15, 0.15))
# data in xts form since quantmod is being used.
my_xts <- xts(df1$Dividend, order.by = df1$Date)
annual_data <- apply.yearly(my_xts, function(x) as.matrix(data.frame(sum(x), length(x))) )
names(annual_data) <- c("total_divs", "no_divs")
# filter data to include only maximum dividens
annual_data[annual_data$no_divs == max(annual_data$no_divs)]
total_divs no_divs
2014-11-01 0.40 4
2015-11-01 0.33 4
2016-11-01 0.52 4
2017-11-01 0.44 4
或使用递归CTE:
WITH omg AS ( -- calendar table
SELECT generate_series( min(tfrom),max(tto),'1sec'::interval) AS ttick
FROM fromto t
)
SELECT t.id, t.tfrom, t.tto
, o.ttick
FROM fromto t
JOIN omg o -- join it with actual table
ON t.tfrom <= o.ttick
AND t.tto >= o.ttick
ORDER BY o.ttick
;