【发布时间】:2016-10-12 07:36:03
【问题描述】:
我有两张桌子:
orders
| id | item_id | quantity | ordered_on |
|----|---------|----------|------------|
| 1 | 1 | 2 | 2016-03-09 |
| 2 | 1 | 2 | 2016-03-12 |
| 3 | 4 | 3 | 2016-03-15 |
| 4 | 4 | 3 | 2016-03-13 |
stocks
| id | item_id | quantity | enter_on | expire_on |
|----|---------|----------|------------|------------|
| 1 | 1 | 10 | 2016-03-07 | 2016-03-10 |
| 2 | 1 | 20 | 2016-03-11 | 2016-03-15 |
| 3 | 1 | 20 | 2016-03-14 | 2016-03-17 |
| 4 | 4 | 10 | 2016-03-14 | NULL |
| 5 | 4 | 10 | 2016-03-12 | NULL |
我正在尝试创建一个视图来显示订单及其最接近的库存enter_on 就像这样(我使用include_after 和include_before 来概述我想排除该项目的日期这是预购的,所以库存会正确反映。)
include_after 始终是进来但尚未过期的库存,如果过期,显示 NULL,include_before 将始终显示下一个库存 enter_on,除非有一个早于的 expire_on下一个enter_on。
| item_id | quantity | ordered_on | include_after | include_before |
|---------|----------|------------|---------------|----------------|
| 1 | 2 | 2016-03-09 | 2016-03-07 | 2016-03-10 |
| 1 | 2 | 2016-03-12 | 2016-03-11 | 2016-03-14 |
| 4 | 3 | 2016-03-13 | 2016-03-12 | 2016-03-14 |
| 4 | 3 | 2016-03-15 | 2016-03-14 | NULL |
所以这就是我想出的:
SELECT
o.item_id, o.quantity, o.order_on, (
SELECT COALESCE(MAX(s.enter_on), NULL::DATE)
FROM stocks s
WHERE s.enter_on <= o.order_on AND s.item_id = o.item_id
) as include_after, (
SELECT COALESCE(MIN(s.enter_on), NULL::DATE)
FROM stocks s
WHERE s.enter_on > o.order_on AND s.item_id = o.item_id
) as include_before
FROM
orders o;
它工作正常(我没有包含expire_on 部分),但我担心在选择中使用两个子查询会出现性能问题。
有人有其他建议吗?
更新
我正在使用 Postgresql 9.4(无法再添加标签)
实际的问题比我说的要复杂得多,很多表和视图连接在一起,如果有替代方案,我将其缩小到一张表以掌握概念
【问题讨论】:
-
实际的表定义会更有用。理想情况下,完整的
CREATE TABLE语句显示数据类型和约束。而且,显然,你的 Postgres 版本。 -
那么你有答案了吗?
标签: sql ruby-on-rails postgresql greatest-n-per-group postgresql-performance