SELECT语句中的MARIADB变量POSTGRES等效

时间:2017-11-28 17:17:33

标签: postgresql plpgsql

在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函数中以这种方式使用变量,或者是否有一种我忽略的替代方法?

1 个答案:

答案 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()