我正在运行PostgreSQL 9.4并具有以下表结构用于开发票:
id BIGINT, time UNIX_TIMESTAMP, customer TEXT, amount BIGINT, status TEXT, billing_id TEXT
我希望我能正确解释我的挑战。
发票记录可以有2种不同的状态; begin
,ongoing
和done
。
随着时间的推移,多个发票记录可以成为同一发票行的一部分。
因此,当发票期间开始时,将启动状态为begin
的记录。
然后,每隔6小时生成一条状态为ongoing
的新记录,其中包含amount
中的当前金额。
关闭发票后,会生成状态为done
的记录,其中包含amount
列中的总金额。同一发票中的所有发票记录都包含相同的billing_id
。
要计算客户目前的支出,我可以执行以下操作:
SELECT sum(amount) FROM invoice_records where id = $1 and time between '2017-06-01' and '2017-07-01' and status = 'done'
但是,如果还有尚未结算的正在进行的发票,则不会考虑这一点。
如何计算没有状态done
的最大billing_id?
希望它有意义。
答案 0 :(得分:1)
每张发票(即billing_id
)您希望记录的金额status = 'done'
(如果存在)或最后一条记录status = 'ongoing'
。您可以使用PostgreSQL的DISTINCT ON
(或使用标准SQL的ROW_NUMBER
对每张发票的记录进行排名)。
SELECT DISTINCT ON (billing_id) billing_id, amount
FROM invoice_records
WHERE status IN ('done', 'ongoing', 'begin')
ORDER BY
billing_id,
CASE status WHEN 'done' THEN 1 WHEN 'ongoing' THEN 2 ELSE 3 END,
unix_timestamp desc;
ORDER BY
子句代表排名。
答案 1 :(得分:0)
select sum (amount), id
from (
select distinct on (billing_id) *
from (
select distinct on (status, billing_id) *
from invoice_records
where
id = $1
and time between '2017-06-01' and '2017-07-01'
and status in ('done', 'ongoing')
order by status, billing_id desc
) s
order by billing_id desc
) s