1

Vertica 的闪亮功能:

我有两个表,我想用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 的数据,则获取该日期可用数据。获取截至日期有效的数据。换句话说,一种回溯行为。只要在该日期之后该 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

但我需要从中选择可用于 id 的最新值b中选择一个 id 可用的最新值,用于(id4,flag,period)的一种分组,而不是它当前给我的结果。有没有办法可以为此使用INTERPOLATE功能?或者我应该采取完全不同的方法。问题是表b中的数据稀疏。我们可能不是每天都有一个数据点,而我们每天都有一个数据点。

我还尝试填补b中数据点之间的空白我还尝试使用TIMESERIES子句和TS_FIRST_VALUE(datapoint, 'const') 填补。但是同样,与 id 中的日期相比,b 中 id4、标志、周期的组合可用的最新日期可能会早于时间。我最终遇到了与上面演示的相同的问题。

任何指导将不胜感激。

4

1 回答 1

1

伊坎,

我无法访问 Vertica 环境来对此进行测试,但我认为您的第二个示例的问题是您的结果集中只有一个日期,因为表中只有一个日期。但是有多个id4。因此,当您询问时,在您的查询中跨日期间隙进行插值时,没有需要插值的间隙。您在 b 表的值中看到的差距实际上是在 a 表的不同 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 环境。

首先,您似乎不能拥有多个插值连接谓词……</p>

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=>

就是这样。

然后我尝试向 a 表添加更多日期,发现您的原始查询确实插入了 b 表字段的间隙......</p>

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)

所以这表明日期插值正在正常工作。

艾伦

于 2013-06-12T17:09:31.173 回答