【发布时间】:2020-08-25 11:44:39
【问题描述】:
我有一个系统来跟踪订单和相关支出。这是一个在 PostgreSQL 上运行的 Rails 应用程序。我的应用程序 99% 都通过普通的旧 Rails Active Record 调用等。这个很丑。
expenditures 表如下所示:
+----+----------+-----------+------------------------+
| id | category | parent_id | note |
+----+----------+-----------+------------------------+
| 1 | order | nil | order with no invoices |
+----+----------+-----------+------------------------+
| 2 | order | nil | order with invoices |
+----+----------+-----------+------------------------+
| 3 | invoice | 2 | invoice for order 2 |
+----+----------+-----------+------------------------+
| 4 | invoice | 2 | invoice for order 2 |
+----+----------+-----------+------------------------+
每个expenditure 有很多expenditure_items 并且可以订单可以是发票的父母。该表如下所示:
+----+----------------+-------------+-------+---------+
| id | expenditure_id | cbs_item_id | total | note |
+----+----------------+-------------+-------+---------+
| 1 | 1 | 1 | 5 | Fuit |
+----+----------------+-------------+-------+---------+
| 2 | 1 | 2 | 15 | Veggies |
+----+----------------+-------------+-------+---------+
| 3 | 2 | 1 | 123 | Fuit |
+----+----------------+-------------+-------+---------+
| 4 | 2 | 2 | 456 | Veggies |
+----+----------------+-------------+-------+---------+
| 5 | 3 | 1 | 34 | Fuit |
+----+----------------+-------------+-------+---------+
| 6 | 3 | 2 | 76 | Veggies |
+----+----------------+-------------+-------+---------+
| 7 | 4 | 1 | 26 | Fuit |
+----+----------------+-------------+-------+---------+
| 8 | 4 | 2 | 98 | Veggies |
+----+----------------+-------------+-------+---------+
我需要跟踪一些事情:
- 剩余的订单发票金额(很简单)
- 以上但为每个
cbs_item_id卷起(这是丑陋的部分)
cbs_item_id 基本上是一个会计代码,用于对所花费的钱等进行分类。我已经可视化了我的最终结果:
+-------------+----------------+-------------+---------------------------+-----------+
| cbs_item_id | expenditure_id | order_total | invoice_total | remaining |
+-------------+----------------+-------------+---------------------------+-----------+
| 1 | 1 | 5 | 0 | 5 |
+-------------+----------------+-------------+---------------------------+-----------+
| 1 | 2 | 123 | 60 | 63 |
+-------------+----------------+-------------+---------------------------+-----------+
| | | | Rollup for cbs_item_id: 1 | 68 |
+-------------+----------------+-------------+---------------------------+-----------+
| 2 | 1 | 15 | 0 | 15 |
+-------------+----------------+-------------+---------------------------+-----------+
| 2 | 2 | 456 | 174 | 282 |
+-------------+----------------+-------------+---------------------------+-----------+
| | | | Rollup for cbs_item_id: 2 | 297 |
+-------------+----------------+-------------+---------------------------+-----------+
order_total 是给定订单(类别 = '订单')的所有支出项目的total 总和。 invoice_total 是 parent_id = 支出.id 的所有支出项目的总和。剩余按差值计算(但不大于 0)。实际上,这里的想法是您下订单并订购 1000 美元和 750 美元的发票。我需要计算订单上剩下的 250 美元(剩余) - 分解为每个类别 (cbs_item_id)。然后我需要汇总由cbs_item_id 分组的所有剩余值。
因此,对于每个cbs_item_id,我需要按每个订单进行分组,找到订单的总额,找到针对订单开具发票的总额,然后减去两者(也不能为负数)。它必须以每个订单为基础 - 总体差异不会返回预期结果。
最终寻找这样的结果:
+-------------+-----------+
| cbs_item_id | remaining |
+-------------+-----------+
| 1 | 68 |
+-------------+-----------+
| 2 | 297 |
+-------------+-----------+
我猜这可能是 GROUP BY 和子查询甚至 CTE(对我来说是巫术)的组合。我的 SQL 技能不是很好,这远远高于我的工资等级。
这是上面数据的一个小提琴:
http://sqlfiddle.com/#!17/2fe3a
备用小提琴:
https://dbfiddle.uk/?rdbms=postgres_11&fiddle=e9528042874206477efbe0f0e86326fb
【问题讨论】:
标签: sql postgresql group-by subquery aggregate-functions