PostgreSQL在子查询中引用外部查询

时间:2015-11-16 21:22:22

标签: sql postgresql

我有两个Postgres表(实际上,不止于此,但为了问题而简化) - 一个是客户订购的产品记录,另一个是每个客户的价格历史记录和日期生效了。像这样:

'订单'表

customer_id | timestamp           | quantity
------------+---------------------+---------
1           | 2015-09-29 16:01:01 | 5
1           | 2015-10-23 14:33:36 | 3
2           | 2015-10-19 09:43:02 | 7
1           | 2015-11-16 15:08:32 | 2

'价格'表

customer_id | effective_time      | price
------------+---------------------+-------
1           | 2015-01-01 00:00:00 | 15.00
1           | 2015-10-01 00:00:00 | 12.00
2           | 2015-01-01 00:00:00 | 14.00

我正在尝试创建一个查询,该订单将在订单时返回该客户的每个订单及其单价,如下所示:

期望的结果

customer_id | quantity | price
------------+----------+------
1           | 5        | 15.00
1           | 3        | 12.00
2           | 7        | 14.00
1           | 2        | 12.00

这基本上就是我想要的,但我知道你不能在内部查询中引用外部查询,而且我无法弄清楚如何重新考虑因素:

SELECT
    o.customer_id,
    o.quantity,
    p.price
FROM orders o
    INNER JOIN (
        SELECT price
        FROM prices x
        WHERE x.customer_id = o.customer_id
            AND x.effective_time <= o.timestamp
        ORDER BY x.effective_time DESC
        LIMIT 1
    ) p
;

有人能建议最好的方法吗?

2 个答案:

答案 0 :(得分:1)

您可以在SELECT列表中执行子查询,而不是基于prices表加入内联视图:

SELECT customer_id, quantity, (
    SELECT price
    FROM prices p
    WHERE
      p.customer_id = o.customer_id
        AND p.effective_time <= o.timestamp
    ORDER BY p.effective_time DESC
    LIMIT 1
  ) AS price
FROM orders o

这确实依赖于相关的子查询,这可能对性能有害,但是对于数据结构的方式,我怀疑是否有更好的选择。

答案 1 :(得分:1)

你不需要子查询,只需要一个简单的内部联接(这假设每个客户没有重复的effective_times):

SELECT o.customer_id, o.quantity
    ,p.price
FROM orders o
JOIN prices p ON p.customer_id = o.customer_id
              AND p.effective_time <= o.timestamp
              AND NOT EXISTS ( SELECT * FROM prices nx
                  WHERE nx.customer_id = o.customer_id
                  AND nx.effective_time <= o.timestamp
                  AND nx.effective_time > p.effective_time
              )
    ;