技术解析

请 sql 老司机来解答解答
0
2021-06-22 13:36:03
idczone

在 https://segmentfault.com/ 上问了个问题,结果并没有人理。

如何用 postgresql 语句实现数据的累加


mysql 可以增加局部变量,select 局部变量做操作就行了

对第二张表 group by id,然后 sum 一下总的消费金额 生成一个临时表 3。剩余金额就是 select (表 1.总金额-表 3.消费金额) from 表 1 join 表 3。不知道是不是这个意思

WITH data AS (
SELECT created_at, id AS card_id, total, total AS amount FROM card
UNION ALL
SELECT transaction.created_at, card_id, card.total, -transaction.total FROM transaction INNER JOIN card ON card_id = card.id)
SELECT created_at, card_id, total, sum(amount) OVER (PARTITION BY card_id ORDER BY created_at) FROM data;
重点是 window function,sum(amount) OVER (PARTITION BY card_id ORDER BY created_at)

我要看看,先谢过。

试过了,可行。再次感谢,之前对 window function 没太多了解。

都上窗函数了为啥不
sum(amount) over(
partition by card_id
order by created_at
rows between unbounded preceding
and current row
)
这个可以计算截至到当前行的支付总额

这种需求建议在业务层处理,窗口函数用起来爽,等到后面加需求的时候,慢慢慢慢的性能就被脱下来了。

你这个 sql 不约束行号不行吧,OVER (PARTITION BY card_id ORDER BY created_at) 这个窗,card_id 相同的记录返回的值都是一样的


楼主都回帖说能用了,那当然是能用的
你加的那个 ROWS BETWEEN ... 是默认值,加不加都一样

默认的 rows between 是 rows between unbounded preceding and unbounded following,楼主的需求是求当前时间的累积,显然要约束在 current row

我说的能用是,理解了这个意思,经过我自己改造后能用。哈哈。

WITH data AS (
SELECT created_at, id AS card_id, total, total AS remaining_total FROM prepay_card
UNION ALL
SELECT pct.created_at, pct.prepay_card_id AS card_id, pc.total, -pct.total AS remaining_total
FROM prepay_card_transaction pct
INNER JOIN prepay_card pc ON pct.prepay_card_id = pc.id
)
SELECT created_at, card_id, total,sum(remaining_total) OVER (PARTITION BY card_id ORDER BY created_at) AS remaining_total_all FROM data
ORDER BY card_id, created_at ;
补充一下我根据 改写的 sql

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服