在mariadb / mysql中,我可以按以下方式使用变量在select语句中执行计算。在这个简单的例子中,我创建了一系列日期并使用变量来计算简单的期初余额和期末余额,每天支付10笔。
with RECURSIVE dates as (
select '2017-11-01' as `dt`
union all
select adddate(dt, INTERVAL 1 DAY)
from dates
where dt < CURDATE()
)
select
@vardate:=d.dt
, @openbal
, @payment:= 10
, @closebal:= @openbal+@payment
, @openbal:=@closebal
from dates d;
给出结果......
╔══════════════╦════════════╦═══════════════╦═════════════╗
║ "ac_date" ║ "open_bal" ║ "trans_total" ║ "close_bal" ║
╠══════════════╬════════════╬═══════════════╬═════════════╣
║ "2017-11-01" ║ "0" ║ "10" ║ "10" ║
║ "2017-11-02" ║ "10" ║ "10" ║ "20" ║
║ "2017-11-03" ║ "20" ║ "10" ║ "30" ║
...
使用这种技术,我可以在select语句中动态执行简单的计算。我的问题是,是否可以在PL / pgSQL函数中以这种方式使用变量,或者是否有一种我忽略的替代方法?
答案 0 :(得分:0)
我不完全确定该声明在MariaDB中是如何工作的,但这似乎做了同样的事情:
with vars (openbal, payment) as (
values (0, 10)
), balance as (
select t.dt::date as ac_date,
openbal,
payment,
sum(payment) over (order by t.dt) as close_bal
from vars,
generate_series(date '2017-11-01', current_date, interval '1' day ) as t(dt)
)
select ac_date,
openbal + lag(close_bal) over (order by ac_date) as open_bal,
payment,
close_bal
from balance;
通常,要获得运行总计,请在SQL中使用sum() over (order by ...)
。要访问上一行的值,请使用lag()
函数。
需要两个CTE,因为窗口函数不能嵌套。
要生成行列表,请在Postgrse中使用generate_series()
。