Postgres中的滚动连接(LOCF)

时间:2014-05-12 16:51:11

标签: r postgresql data.table

随着时间的推移,我已经习惯了data.tabler滚动连接的非常有用的功能。这些利用了LOCF的操作(最后的观察结果)。不幸的是,我被迫在一个我不太熟悉的环境中工作(使用postgres)。 SQL中是否有类似的操作(特别是postgres)?

以下是我所拥有的和我想要的输出的示例:

这是我的第一张表

dt1 = data.table(Date=seq(from=as.Date("2013-01-03"),
         to=as.Date("2013-06-27"), by="1 day"),key="Date")[, ind:=.I]

           Date ind
  1: 2013-01-03   1
  2: 2013-01-04   2
  3: 2013-01-05   3
  4: 2013-01-06   4
  5: 2013-01-07   5
 ---               
172: 2013-06-23 172
173: 2013-06-24 173
174: 2013-06-25 174
175: 2013-06-26 175
176: 2013-06-27 176

这是我的第二张表

dt2 = data.table(Date=seq(from=as.Date("2013-01-01"),
         to=as.Date("2013-06-30"), by="1 week"),key="Date")

          Date
 1: 2013-01-01
 2: 2013-01-08
 3: 2013-01-15
 4: 2013-01-22
 5: 2013-01-29
 ---
22: 2013-05-28
23: 2013-06-04
24: 2013-06-11
25: 2013-06-18
26: 2013-06-25

以下是我在data.table中用于所需输出的代码。

dt1[dt2, roll=Inf]

          Date ind
 1: 2013-01-01  NA
 2: 2013-01-08   6
 3: 2013-01-15  13
 4: 2013-01-22  20
 5: 2013-01-29  27
---
22: 2013-05-28 146
23: 2013-06-04 153
24: 2013-06-11 160
25: 2013-06-18 167
26: 2013-06-25 174

使用postgres(或更一般地说,SQL甚至可以实现这一点吗?非常感谢您提供的任何帮助。

2 个答案:

答案 0 :(得分:4)

我真的很想知道是否有人可以在不填充完整的交叉连接表的情况下执行此操作。但这是一个交叉加入的解决方案:

http://sqlfiddle.com/#!2/b2f3f/3/0

创建架构:

CREATE TABLE Table1
    (`t1` double, `ind` int)
;

INSERT INTO Table1
    (`t1`, `ind`)
VALUES
    (1, 1),
    (1.9, 2),
    (3.1, 3),
    (4, 4),
    (5.1, 5),
    (5.9, 6)
;

CREATE TABLE Table2
    (`t2` int)
;

INSERT INTO Table2
    (`t2`)
VALUES
    (1),
    (2),
    (3),
    (4),
    (5),
    (6)
;

查询:

select t2, max(ind)
from (select t2, ind
      from table1
      cross join table2
      where t1 <= t2) as foo
group by t2

结果:

T2  MAX(IND)
1   1
2   2
3   2
4   4
5   4
6   6

编辑:@Hadley的评论是正确的,使用上面的查询从未实现完整的交叉连接表,因为上面的查询产生与下面的查询相同的解释和结果:

select t2, max(ind)
from table1
cross join table2
where t1 <= t2
group by t2

答案 1 :(得分:2)

由于我在一个特殊的Postgres环境中工作,显然它不允许我交叉加入。非常感谢@Clayton Stanley提供了很好的答案,但我不得不尝试另一条路线。它似乎到目前为止工作。我为无法对两种方法进行时间比较而道歉。

创建架构

CREATE TABLE Table1
    (`id` int,`t1` double, `ind` int)
;

INSERT INTO Table1
    (`id`,`t1`, `ind`)
VALUES
    (1,0.99, 5),
    (1,1.90, 10),
    (2,3.10, 12),
    (2,4.00, 3),
    (3,5.10, 8),
    (3,5.90, 16),
    (4,5.90, 7),
    (4,5.99, 20)
;



CREATE TABLE Table2
    (`id` int, `t2` double)
;

INSERT INTO Table2
    (`id`,`t2`)
VALUES
    (1,1.00),
    (2,3.95),
    (3,5.05),
    (4,6.01)
;

使用子查询执行连接

select B.*
from Table2 as A
join Table1 as B
on B.id=A.id
join(
    select 
       SUBB.id,
       max(SUBB.t1) as t1
    from Table2 as SUBA
    join Table1 as SUBB
    on SUBB.id=SUBA.id and
    SUBB.t1 <= SUBA.t2
    group by SUBB.id
    )
as subqry
on B.t1=subqry.t1  and
   A.id=subqry.id

示例架构和输出在这里:

Link to schema