如何在另一个表中加入最接近的前一个日期的记录?

时间:2013-10-15 18:02:37

标签: sql subquery vertica vsql

我想制作一份销售报告,显示每件产品在销售时的价格。定价存储在单独的价格历史记录表中,因此我想加入销售日期之前的最新价格。

我知道如何实现查询,但我正在使用的数据库(Vertica)似乎不支持我想要做的事情。

这是表结构的简化版本:

Sales
-----
Date      Product ID
1/1/2001  1
2/2/2002  1
3/3/2003  1

PriceHistory
-------------
Date        ProductID     Price
12/31/2000  1             1.00
12/31/2001  1             1.01
12/31/2002  1             1.11

以下是我想从上述数据生成的报告示例:

Sales Report
------------
Date       ProductID     Price
1/1/2001   1             1.00
2/2/2002   1             1.01
3/3/2003   1             1.11

这是我到目前为止编写的SQL:

SELECT s.date,
       s.productid,
       ph.price
FROM Sales s,
     PriceHistory ph
WHERE s.productid=ph.productid
  AND ph.date=
    (SELECT MAX(date)
     FROM PriceHistory
     WHERE productid=s.productid
       AND date < s.date)

这可能适用于另一个数据库平台,但Vertica给了我这个错误:“不支持非等式相关的子查询表达式”。它不喜欢我的子查询的date < s.date组件。

还有其他办法吗?

后来,我找到了一个适用于Vertica的解决方法,使用了对查询中PriceHistory表的两个不同引用:

SELECT s.date,
       s.productid,
       ph.price
FROM Sales s
JOIN PriceHistory ph ON ph.date < s.date
WHERE s.productid=ph.productid
  AND ph.date=
    (SELECT MAX(date)
     FROM PriceHistory ph2
     WHERE ph2.productid=s.productid
       AND ph2.date = ph.date)

可能有更好的方法,如果是这样,我很乐意听到它。

2 个答案:

答案 0 :(得分:2)

尝试JOIN INTERPOLATE子句。对于您的示例,以下示例完全按照您的要求生成:

SELECT s.date,
   s.productid,
   ph.price
FROM Sales s
left outer join PriceHistory ph  ON  s.date INTERPOLATE
    PREVIOUS VALUE ph.date
where s.productid=ph.productid

答案 1 :(得分:1)

问题在于:

  SELECT MAX(date)
  FROM PriceHistory
  WHERE productid=s.productid
   AND date < s.date

未定义S ...子查询是独立的,不能引用“外部”查询中from语句中的表。只需在子查询中加入。

SELECT MAX(date)
 FROM PriceHistory ph, Sales s
 WHERE ph.productid=s.productid
   AND date < s.date

当我在MySQL时,我感到嫉妒,知道其他人可以在Vertica上玩。啊..

应该提到您使用的是旧语法,其中大部分都可以作为连接来完成。调用max_date一个子查询并将其移动到from语句... inner join函数作为该级别的过滤器。

编辑:

如果失败了,它的顶点有一些子查询问题......已经有一段时间但是我想我过去已经解决了这个问题(有了vertica支持):

SELECT s.date,
   s.productid,
   ph.price
FROM Sales s,
 PriceHistory ph,
(SELECT MAX(date)
  FROM PriceHistory ph, Sales s
  WHERE ph.productid=s.productid
AND date < s.date) a
WHERE s.productid=ph.productid
AND ph.date= max_date

试试那个版本......如果失败了,我会回到vertica支持并询问他们如何处理它(功能上,你要求的应该是标准的,我认为vertica只是略有改变了到达那里的方式......我记得被要求避免在where子句中使用子查询。