我有两个表格,我想加入 INTERPOLATE ,并希望第二个表格中的数据用最新的可用内容进行插值。但不幸的是,我无法得到我想要的结果。 我查看了与INTERPOLATE功能相关的Vertica文档,并尝试了一个工作正常的示例。
CREATE TABLE a
( family int,
date DATE,
id int
);
CREATE TABLE b
( Id int,
date DATE,
datapoint float
);
INSERT INTO a VALUES (1, '20130603', 1);
INSERT INTO a VALUES (1, '20130604', 1);
INSERT INTO a VALUES (1, '20130605', 1);
INSERT INTO a VALUES (1, '20130606', 1);
INSERT INTO a VALUES (1, '20130607', 1);
INSERT INTO b VALUES (1, '20130603', 3.00);
SELECT a.family, a.date, a.id, a.date, b.datapoint
FROM a
LEFT
JOIN b
ON a.id = b.id
AND a.date INTERPOLATE PREVIOUS VALUE b.date;
vertdeva01:20130612-095628 > \g
family | date | id | date | data
--------+------------+----+------------+------
1 | 2013-06-03 | 1 | 2013-06-03 | 3
1 | 2013-06-04 | 1 | 2013-06-04 | 3
1 | 2013-06-05 | 1 | 2013-06-05 | 3
1 | 2013-06-06 | 1 | 2013-06-06 | 3
1 | 2013-06-07 | 1 | 2013-06-07 | 3
我得到了预期的结果。表 b 中的值根据表 a 中的日期进行插值。
但是当我尝试类似于稍微复杂的情况时,我并没有真正得到我想要的东西。
我打算通过 b 为 a 中与 a 中的相应日期匹配的每个ID选择最新的可用数据>。因此,如果 a 具有(id,date)组合,那么我想从 b 获取该ID和日期的数据。但是如果该日期的b中没有该ID的数据,则获取该日期可用的 AS OF 。从 a 中获取截至日期有效的数据。换句话说,一种感觉回归的行为。只要在该日期之后该ID没有其他数据点,则id的数据点在 b 中有效。我希望这是有道理的。我知道使用MAX()
和GROUP BY
执行此操作的方法。我想知道使用INTERPOLATE
为了让你知道它是什么,我玩了一个例子。这次我只修改了以前创建的表以获得更多字段。
CREATE TABLE a
( family int,
family_name varchar(50),
industry varchar(15),
style_flag varchar(1),
id int,
id_name varchar(50),
id1 int,
id2 int,
id3 int,
date DATE,
id4 int
);
CREATE TABLE b
( id4 int,
flag int,
period int,
date DATE,
datapoint float
);
INSERT INTO a VALUES (1, '1family', 'comp', 'A', 1, '1 id', 101, 201, 301, '20130603', 401);
INSERT INTO a VALUES (1, '1family', 'comp', 'A', 2, '2 id', 102, 202, 302, '20130603', 402);
INSERT INTO a VALUES (1, '1family', 'comp', 'A', 3, '3 id', 103, 203, 303, '20130603', 403);
INSERT INTO a VALUES (2, '2family', 'bio', 'A', 5, '5 id', 105, 205, 305, '20130603', 405);
INSERT INTO a VALUES (2, '2family', 'bio', 'A', 7, '7 id', 107, 207, 307, '20130603', 407);
INSERT INTO a VALUES (2, '2family', 'bio', 'A', 9, '9 id', 109, 209, 309, '20130603', 409);
INSERT INTO b VALUES (401, 1, 10, '20130501', 2.00);
INSERT INTO b VALUES (401, 1, 20, '20130501', 1.50);
INSERT INTO b VALUES (401, 2, 10, '20130409', 12.34);
INSERT INTO b VALUES (401, 2, 20, '20130401', 10.56);
INSERT INTO b VALUES (402, 1, 10, '20130501', 2.00);
INSERT INTO b VALUES (402, 2, 20, '20130409', 12.34);
INSERT INTO b VALUES (402, 2, 20, '20130401', 10.56);
INSERT INTO b VALUES (402, 2, 20, '20130515', 20.55);
当我运行以下查询时:
SELECT a.family, a.family_name, a.industry, a.style_flag,
a.id, a.id_name,
a.id1, a.id2, a.id3, a.date,
b.id4, b.flag, b.period, b.datapoint
FROM a
LEFT
JOIN b
ON a.id4 = b.id4
AND a.date INTERPOLATE PREVIOUS VALUE b.date;
我得到以下内容:
family | family_name | industry | style_flag | id | id_name | id1 | id2 | id3 | date | id4 | flag | period | datapoint
--------+-------------+----------+------------+----+---------+-----+-----+-----+------------+-----+------+--------+-----------
2 | 2family | bio | A | 5 | 5 id | 105 | 205 | 305 | 2013-06-03 | | | |
1 | 1family | comp | A | 1 | 1 id | 101 | 201 | 301 | 2013-06-03 | 401 | 1 | 10 | 2
1 | 1family | comp | A | 3 | 3 id | 103 | 203 | 303 | 2013-06-03 | | | |
2 | 2family | bio | A | 9 | 9 id | 109 | 209 | 309 | 2013-06-03 | | | |
2 | 2family | bio | A | 7 | 7 id | 107 | 207 | 307 | 2013-06-03 | | | |
1 | 1family | comp | A | 2 | 2 id | 102 | 202 | 302 | 2013-06-03 | 402 | 2 | 20 | 20.55
但是我需要从 b 中选择一个ID可用的最新值,用于(id4,flag,period)的一种组,而不是它当前给我的结果。 有没有办法可以使用 INTERPOLATE 功能?或者我应该采取完全不同的方法。 问题是表格中的数据 b 是稀疏的。我们可能每天都没有数据点,而 a 我们每天都有一个数据点。
我还尝试使用 TIMESERIES 子句和 TS_FIRST_VALUE(datapoint,'const')填补 b 中数据点之间的空白。但同样,与 a 中的ID日期相比, b 中id4,flag,period组合的最新日期可能会回溯。我最终遇到了与上面说明的相同的问题。
任何指导都将受到高度赞赏。
答案 0 :(得分:1)
Eakan,
我没有访问Vertica环境来测试这个,但我认为你的第二个例子的问题是你的结果集只有一个日期,因为一个表中只有一个日期。但是有多个id4。因此,当您询问时,在您的查询中跨日期间隙进行插值时,插值没有间隙。您在b表的值中看到的间隙实际上是来自表中的不同id4值。
我不确定你是否可以在join子句中有多个插值但是如何:
SELECT a.family, a.family_name, a.industry, a.style_flag, a.id, a.id_name,
a.id1, a.id2, a.id3, a.date, a.id4, b.id4, b.flag, b.period, b.datapoint
FROM a
LEFT JOIN b
ON a.id4 INTERPOLATE PREVIOUS VALUE b.id4 AND
a.date INTERPOLATE PREVIOUS VALUE b.date;
我认为这会填充b表中的值,但这可能不是你想要的。也许你只是想对日期进行插值,并且你认为它不起作用只是因为你的表中没有多个日期。在表中添加几个日期,然后重新运行查询以查看我的意思。
如果您想更详细地讨论,请离线与我联系。如果您可以通过访问工作的Vertica环境来与我联系,那么我可以为您尝试更多的想法。
艾伦
关注:
好的,所以我设法访问了测试Vertica环境。
首先,您似乎不能拥有多个插值连接谓词...
vmartdb=> SELECT a.family, a.family_name, a.industry, a.style_flag, a.id, a.id_name,
vmartdb-> a.id1, a.id2, a.id3, a.date, a.id4, b.id4, b.flag, b.period, b.datapoint
vmartdb-> FROM est_cal.a AS a
vmartdb-> LEFT JOIN est_cal.b AS b
vmartdb-> ON a.id4 INTERPOLATE PREVIOUS VALUE b.id4 AND
vmartdb-> a.date INTERPOLATE PREVIOUS VALUE b.date;
ERROR 2093: A join can have only one set of interpolated predicates
vmartdb=>
就是这样。
然后我尝试在表格中添加几个日期,看到你的原始查询确实插入了b表字段的间隙......
CREATE TABLE est_cal.a (
family int,
family_name varchar(50),
industry varchar(15),
style_flag varchar(1),
id int,
id_name varchar(50),
id1 int,
id2 int,
id3 int,
date DATE,
id4 int
);
CREATE TABLE est_cal.b (
id4 int,
flag int,
period int,
date DATE,
datapoint float
);
INSERT INTO est_cal.a VALUES (1, '1family', 'comp', 'A', 1, '1 id', 101, 201, 301, '20130603', 401);
INSERT INTO est_cal.a VALUES (1, '1family', 'comp', 'A', 2, '2 id', 102, 202, 302, '20130603', 402);
INSERT INTO est_cal.a VALUES (1, '1family', 'comp', 'A', 3, '3 id', 103, 203, 303, '20130603', 403);
INSERT INTO est_cal.a VALUES (2, '2family', 'bio', 'A', 5, '5 id', 105, 205, 305, '20130603', 405);
INSERT INTO est_cal.a VALUES (2, '2family', 'bio', 'A', 7, '7 id', 107, 207, 307, '20130603', 407);
INSERT INTO est_cal.a VALUES (2, '2family', 'bio', 'A', 9, '9 id', 109, 209, 309, '20130603', 409);
INSERT INTO est_cal.a VALUES (1, '1family', 'comp', 'A', 1, '1 id', 101, 201, 301, '20130604', 401);
INSERT INTO est_cal.a VALUES (1, '1family', 'comp', 'A', 2, '2 id', 102, 202, 302, '20130604', 402);
INSERT INTO est_cal.a VALUES (1, '1family', 'comp', 'A', 3, '3 id', 103, 203, 303, '20130604', 403);
INSERT INTO est_cal.a VALUES (2, '2family', 'bio', 'A', 5, '5 id', 105, 205, 305, '20130605', 405);
INSERT INTO est_cal.a VALUES (2, '2family', 'bio', 'A', 7, '7 id', 107, 207, 307, '20130605', 407);
INSERT INTO est_cal.a VALUES (2, '2family', 'bio', 'A', 9, '9 id', 109, 209, 309, '20130605', 409);
INSERT INTO est_cal.a VALUES (1, '1family', 'comp', 'A', 1, '1 id', 101, 201, 301, '20130605', 401);
INSERT INTO est_cal.a VALUES (1, '1family', 'comp', 'A', 2, '2 id', 102, 202, 302, '20130605', 402);
INSERT INTO est_cal.a VALUES (1, '1family', 'comp', 'A', 3, '3 id', 103, 203, 303, '20130605', 403);
INSERT INTO est_cal.a VALUES (2, '2family', 'bio', 'A', 5, '5 id', 105, 205, 305, '20130605', 405);
INSERT INTO est_cal.a VALUES (2, '2family', 'bio', 'A', 7, '7 id', 107, 207, 307, '20130605', 407);
INSERT INTO est_cal.a VALUES (2, '2family', 'bio', 'A', 9, '9 id', 109, 209, 309, '20130605', 409);
INSERT INTO est_cal.b VALUES (401, 1, 10, '20130501', 2.00);
INSERT INTO est_cal.b VALUES (401, 1, 20, '20130501', 1.50);
INSERT INTO est_cal.b VALUES (401, 2, 10, '20130409', 12.34);
INSERT INTO est_cal.b VALUES (401, 2, 20, '20130401', 10.56);
INSERT INTO est_cal.b VALUES (402, 1, 10, '20130501', 2.00);
INSERT INTO est_cal.b VALUES (402, 2, 20, '20130409', 12.34);
INSERT INTO est_cal.b VALUES (402, 2, 20, '20130401', 10.56);
INSERT INTO est_cal.b VALUES (402, 2, 20, '20130515', 20.55);
SELECT a.family, a.family_name, a.industry, a.style_flag, a.id, a.id_name,
a.id1, a.id2, a.id3, a.date AS a_date, b.date AS b_date, a.id4 AS a_id4, b.id4 AS b_id4, b.flag, b.period, b.datapoint
FROM est_cal.a AS a
LEFT JOIN est_cal.b AS b
ON a.id4 = b.id4 AND
a.date INTERPOLATE PREVIOUS VALUE b.date;
这产生了以下结果......
family | family_name | industry | style_flag | id | id_name | id1 | id2 | id3 | a_date | b_date | a_id4 | b_id4 | flag | period | datapoint
--------+-------------+----------+------------+----+---------+-----+-----+-----+------------+------------+-------+-------+------+--------+-----------
2 | 2family | bio | A | 7 | 7 id | 107 | 207 | 307 | 2013-06-03 | | 407 | | | |
2 | 2family | bio | A | 7 | 7 id | 107 | 207 | 307 | 2013-06-04 | | 407 | | | |
2 | 2family | bio | A | 7 | 7 id | 107 | 207 | 307 | 2013-06-05 | | 407 | | | |
2 | 2family | bio | A | 7 | 7 id | 107 | 207 | 307 | 2013-06-05 | | 407 | | | |
2 | 2family | bio | A | 5 | 5 id | 105 | 205 | 305 | 2013-06-03 | | 405 | | | |
2 | 2family | bio | A | 5 | 5 id | 105 | 205 | 305 | 2013-06-04 | | 405 | | | |
2 | 2family | bio | A | 5 | 5 id | 105 | 205 | 305 | 2013-06-05 | | 405 | | | |
2 | 2family | bio | A | 5 | 5 id | 105 | 205 | 305 | 2013-06-05 | | 405 | | | |
2 | 2family | bio | A | 9 | 9 id | 109 | 209 | 309 | 2013-06-03 | | 409 | | | |
2 | 2family | bio | A | 9 | 9 id | 109 | 209 | 309 | 2013-06-04 | | 409 | | | |
2 | 2family | bio | A | 9 | 9 id | 109 | 209 | 309 | 2013-06-05 | | 409 | | | |
2 | 2family | bio | A | 9 | 9 id | 109 | 209 | 309 | 2013-06-05 | | 409 | | | |
1 | 1family | comp | A | 1 | 1 id | 101 | 201 | 301 | 2013-06-03 | 2013-05-01 | 401 | 401 | 1 | 10 | 2
1 | 1family | comp | A | 1 | 1 id | 101 | 201 | 301 | 2013-06-04 | 2013-05-01 | 401 | 401 | 1 | 10 | 2
1 | 1family | comp | A | 1 | 1 id | 101 | 201 | 301 | 2013-06-05 | 2013-05-01 | 401 | 401 | 1 | 10 | 2
1 | 1family | comp | A | 3 | 3 id | 103 | 203 | 303 | 2013-06-03 | | 403 | | | |
1 | 1family | comp | A | 3 | 3 id | 103 | 203 | 303 | 2013-06-04 | | 403 | | | |
1 | 1family | comp | A | 3 | 3 id | 103 | 203 | 303 | 2013-06-05 | | 403 | | | |
1 | 1family | comp | A | 2 | 2 id | 102 | 202 | 302 | 2013-06-03 | 2013-05-15 | 402 | 402 | 2 | 20 | 20.55
1 | 1family | comp | A | 2 | 2 id | 102 | 202 | 302 | 2013-06-04 | 2013-05-15 | 402 | 402 | 2 | 20 | 20.55
1 | 1family | comp | A | 2 | 2 id | 102 | 202 | 302 | 2013-06-05 | 2013-05-15 | 402 | 402 | 2 | 20 | 20.55
(21 rows)
因此,这表明日期插值正常工作。
艾伦