将表格结果合并到列中(pivot / crosstab?)

时间:2017-04-05 14:30:12

标签: sql postgresql

我有~30个桌子,其中包含#34;流式传输"来自外部系统的数据。我试图弄清楚如何检索特定时间点的表的最后已知值并以方便的方式呈现。

让我们来描述表格布局:

DROP TABLE IF EXISTS table1;
DROP TABLE IF EXISTS table2;
CREATE TABLE IF NOT EXISTS table1 (
    id1             INT NOT NULL,
    id2             TEXT NOT NULL,
    update_time     TIMESTAMP(6) NOT NULL,
    val             NUMERIC NULL,
    PRIMARY KEY (id1, id2, update_time)
)
;

CREATE TABLE IF NOT EXISTS table2 (
    id1             INT NOT NULL,
    id2             TEXT NOT NULL,
    update_time     TIMESTAMP(6) NOT NULL,
    val             INT NULL,
    PRIMARY KEY (id1, id2, update_time)
)
;

--...tableN(


INSERT INTO table1(id1, id2, update_time, val) VALUES (1, 'ident 1', '2004-10-19 09:00:00', 1.23);
INSERT INTO table1(id1, id2, update_time, val) VALUES (1, 'ident 1', '2004-10-19 10:05:00', 1.25);

INSERT INTO table2(id1, id2, update_time, val) VALUES (1, 'ident 1', '2004-10-19 10:03:00', 23);
INSERT INTO table2(id1, id2, update_time, val) VALUES (1, 'ident 1', '2004-10-19 10:03:30', null);

现在,我提供数据的最佳方式是:

SELECT *
FROM lastknownvalues
WHERE id1 = 1
AND id2 = 'ident 1'
AND time = '2004-10-19 10:04:00'

哪一行会返回一行:

time                     id1    id2     table1    table2
'2004-10-19 10:04:00'    1      ident1  1.23      null

在10:04:00,table1中的最后一个已知值是1.23(稍后更新到1.25) table2在10:03:30更新为null,因此结果中应该为null。 请注意,val的数据类型在表中是不同的。

我一直在使用pivot / crosstab,因为它看起来已经足够接近我正在寻找的功能但是我无法弄清楚如何去做,你能搞清楚吗? :)

跟进问题:

如果我想检索一个时间间隔内的所有值,以获取两个时间戳之间的所有组合信息,该怎么办? 例如,如果选择start_timestamp 2004-10-19 09:00:00和end_timestamp 2004-10-19 10:04:00得到如下结果:

time                     id1    id2     table1    table2
'2004-10-19 09:00:00'    1      ident1  1.23      null
'2004-10-19 10:03:00'    1      ident1  1.23      23
'2004-10-19 10:03:30'    1      ident1  1.23      null

可能..? (请注意,我在~30个表中获得数据以与上述所需输出结合)

1 个答案:

答案 0 :(得分:1)

要查找最新的时间戳,请先使用比较运算符排除将来的时间戳。接下来,通过从期望的时间戳中减去可能的时间戳候选,按最小间隔排序。要获得最新结果,请限制1。

要使用table1列显示table2 val列,只需在子查询中为table2运行相同的代码。

SELECT update_time AS time, id1, id2, val, (
  SELECT val from table2 
  WHERE '2004-10-19 10:04:00' >= update_time
  ORDER BY '2004-10-19 10:04:00' - update_time
  LIMIT 1
)
FROM table1 WHERE '2004-10-19 10:04:00' >= update_time
ORDER BY '2004-10-19 10:04:00' - update_time
LIMIT 1;