每行的不同条件的总和

时间:2018-04-16 08:15:03

标签: postgresql postgresql-9.3

在我的Postgresql 9.3数据库中,我有一个表stock_rotation

+----+-----------------+---------------------+------------+---------------------+
| id | quantity_change | stock_rotation_type | article_id |        date         |
+----+-----------------+---------------------+------------+---------------------+
|  1 |              10 | PURCHASE            |          1 | 2010-01-01 15:35:01 |
|  2 |              -4 | SALE                |          1 | 2010-05-06 08:46:02 |
|  3 |               5 | INVENTORY           |          1 | 2010-12-20 08:20:35 |
|  4 |               2 | PURCHASE            |          1 | 2011-02-05 16:45:50 |
|  5 |              -1 | SALE                |          1 | 2011-03-01 16:42:53 |
+----+-----------------+---------------------+------------+---------------------+

类型:

  • SALE的结果为quantity_change
  • PURCHASE有正面quantity_change
  • INVENTORY将库存中的实际数量重置为给定值

在此实施中,要获取商品库存的当前值,您需要总结自特定商品的最新INVENTORY以来的所有数量更改(包括库存值)。我不知道为什么以这种方式实现它,不幸的是现在很难改变它。

我现在的问题是如何同时为多篇文章做这件事。

我最近的尝试是:

WITH latest_inventory_of_article as (
    SELECT MAX(date)
    FROM stock_rotation
    WHERE stock_rotation_type = 'INVENTORY'
)
SELECT a.id, sum(quantity_change)
FROM stock_rotation sr
INNER JOIN article a ON a.id = sr.article_id
WHERE sr.date >= (COALESCE(
                     (SELECT date FROM latest_inventory_of_article),
                     '1970-01-01'
                 ))
GROUP BY a.id

但每个文章的stock_rotation类型INVENTORY的最新日期可能不同。 我试图避免在多个文章ID上循环以找到这个日期。

3 个答案:

答案 0 :(得分:1)

在这种情况下,我会使用不同的内部查询来获取每篇文章的最大库存。你有效地使用stock_rotation两次,但它应该工作。如果它太大了,你可以尝试别的东西:

SELECT sr.article_id, sum(quantity_change)
FROM stock_rotation sr
LEFT JOIN (
    SELECT article_id, MAX(date) AS date
    FROM stock_rotation
    WHERE stock_rotation_type = 'INVENTORY'
    GROUP BY article_id) AS latest_inventory
    ON latest_inventory.article_id = sr.article_id
WHERE sr.date >= COALESCE(latest_inventory.date, '1970-01-01')
GROUP BY sr.article_id

答案 1 :(得分:0)

您可以将DISTINCT ONORDER BY一起使用,以获取INVENTORY子句中每个article_id的最新WITH行。

然后,您可以将其与原始表连接,以获取所有后续行并添加值:

WITH latest_inventory as (
    SELECT DISTINCT ON (article_id) id, article_id, date
    FROM stock_rotation
    WHERE stock_rotation_type = 'INVENTORY'
    ORDER BY article_id, date DESC
)
SELECT article_id, sum(sr.quantity_change)
FROM stock_rotation sr
    JOIN latest_inventory li USING (article_id)
WHERE sr.date >= li.date
GROUP BY article_id;

答案 2 :(得分:0)

以下是我的看法:首先,使用窗口函数构建上次库存状态的产品列表。然后,将其连接回整个列表,过滤项目的库存日期之后的操作。

with initial_inventory as
(
select article_id, date, quantity_change from
(select article_id, date, quantity_change, rank() over (partition by article_id order by date desc)
from stockRotation
where type = 'INVENTORY'
) a
where rank = 1
)
select ii.article_id, ii.quantity_change + sum(sr.quantity_change)
from initial_inventory ii
join stockRotation sr on ii.article_id = sr.article_id and sr.date > ii.date
group by ii.article_id, ii.quantity_change