每行的不同条件求和
Sum with different condition for every line
在我的 Postgresql 9.3 数据库中,我有一个 table 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
但是每篇文章的 INVENTORY
类型的最新 stock_rotation
的日期可能不同。
我试图避免循环遍历多个文章 ID 来查找此日期。
您可以将 DISTINCT ON
与 ORDER BY
一起使用以获得 WITH
子句中每个 article_id
的最新 INVENTORY
行。
然后您可以将其与原始 table 连接起来以获取所有后面的行并添加值:
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;
以下是我的看法:首先,使用 window 函数构建处于最后库存状态的产品列表。然后,将其加入到整个列表中,过滤晚于项目库存日期的操作。
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
在这种情况下,我将使用不同的内部查询来获取每篇文章的最大库存。您有效地使用了 stock_rotation 两次,但它应该可以工作。如果 table 太大,您可以尝试其他方法:
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
在我的 Postgresql 9.3 数据库中,我有一个 table 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
但是每篇文章的 INVENTORY
类型的最新 stock_rotation
的日期可能不同。
我试图避免循环遍历多个文章 ID 来查找此日期。
您可以将 DISTINCT ON
与 ORDER BY
一起使用以获得 WITH
子句中每个 article_id
的最新 INVENTORY
行。
然后您可以将其与原始 table 连接起来以获取所有后面的行并添加值:
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;
以下是我的看法:首先,使用 window 函数构建处于最后库存状态的产品列表。然后,将其加入到整个列表中,过滤晚于项目库存日期的操作。
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
在这种情况下,我将使用不同的内部查询来获取每篇文章的最大库存。您有效地使用了 stock_rotation 两次,但它应该可以工作。如果 table 太大,您可以尝试其他方法:
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