【问题标题】:How can I write a function with two tables inputs and one table output in PostgreSQL?如何在 PostgreSQL 中编写具有两个表输入和一个表输出的函数?
【发布时间】:2020-08-24 01:43:35
【问题描述】:

我想创建一个可以创建表的函数,其中的部分列是从其他两个表中派生出来的。

输入表1: 这是每笔贷款的静态表。每笔贷款只有一行包含与该贷款相关的信息。例如原始未付余额、原始利率...

| id  | loan_age | ori_upb | ori_rate | ltv |
| --- | -------- | ------- | -------- | --- |
| 1   | 360      | 1500    | 4.5      | 0.6 |
| 2   | 360      | 2000    | 3.8      | 0.5 |

输入表2: 这是每笔贷款的动态表。每笔贷款都有若干行显示每个月的贷款表现。例如,当前未付余额、当前利率、拖欠状况...

| id | month| cur_upb | cur_rate |status|
| ---| ---  | ------- | -------- | ---  |
| 1  | 01   | 1400    | 4.5      | 0    |
| 1  | 02   | 1300    | 4.5      | 0    |
| 1  | 03   | 1200    | 4.5      | 1    |
| 2  | 01   | 2000    | 3.8      | 0    |
| 2  | 02   | 1900    | 3.8      | 0    |
| 2  | 03   | 1900    | 3.8      | 1    |
| 2  | 04   | 1900    | 3.8      | 2    |

输出表: 输出表包含来自 table1 和 table2 的信息。 payoffupb 是表 2 中 cur_upb 的最后一条记录。此表是为模型开发而构建的。

| id | loan_age | ori_upb | ori_rate | ltv | payoffmonth| payoffupb | payoffrate |lastStatus | modification |
| ---| -------- | ------- | -------- | --- | ---------- | --------- | ---------- |---------- | ------------ |
| 1  | 360      | 1500    | 4.5      | 0.6 |   03       | 1200      |  4.5       |  1        |  null        |
| 2  | 360      | 2000    | 3.8      | 0.5 |   04       | 1900      |  3.8       |  2        |  null        |

输出表中的大部分列可以直接从两个输入表中的列获取或转移,但有些列无法获取则留空。

我的主要问题是如何编写一个函数以将两个表作为输入并输出另一个表? 我已经在 2018 年为数据文件编写了特征转换部分,但我需要在其他年份再次为数据文件做同样的事情。这就是为什么我想创建一个函数来让事情变得更简单。

【问题讨论】:

  • 请解释payoffmonthpayoffupbpayoffratelaststatus 列是如何计算的?为什么 01 和 02 月份没有出现在输出中?选择第 03 个月的一行而不是另一行的规则是什么?如果第 4 个月还有 3 行呢?
  • 嗨,很抱歉造成混乱。我用更多解释更新了我的问题。但我的问题主要是关于如何编写一个两表输入和一表输出的函数。我已经做了特征转换部分,这里只是一个简单的演示,但我想对其他类似的表格文件应用相同的东西。

标签: postgresql function


【解决方案1】:

如果您想在 table1 的每个条目上插入 table2 的最新条目,请尝试此操作

    insert into table3 (id,  loan_age,  ori_upb,  ori_rate,  ltv,  
                        payoffmonth, payoffupb,  payoffrate, lastStatus )
    select distinct on (t1.id) 
           t1.id, t1.loan_age, t1.ori_upb, t1.ori_rate, t1.ltv, t2.month, t2.cur_upb,
           t2.cur_rate, t2.status 
    from 
        table1 t1 
    inner join 
        table2 t2 on t1.id=t2.id 
    order by t1.id , t2.month desc

DEMO1

编辑您更新的问题:

考虑到table1, table2, table3 结构,执行上述操作的功能将始终相同。

create or replace function insert_values(table1 varchar, table2 varchar, table3 varchar)
returns int as $$
declare 
count_ int;
begin

execute format('insert into %I (id,  loan_age,  ori_upb,  ori_rate,  ltv,  payoffmonth, payoffupb,  payoffrate, lastStatus )
select distinct on (t1.id) t1.id, t1.loan_age, t1.ori_upb,
t1.ori_rate,t1.ltv,t2.month,t2.cur_upb, t2.cur_rate, t2.status 
from %I t1 inner join %I t2 on t1.id=t2.id order by t1.id , t2.month desc',table3,table1,table2);
GET DIAGNOSTICS count_ = ROW_COUNT;
return count_;
end;
$$
language plpgsql

并调用上面的函数,如下所示,它将返回插入的行数:

select * from insert_values('table1','table2','table3');

DEMO2

【讨论】:

  • 您好,感谢您的帮助!如果我有很多table1和table2,如何编写一个函数来处理每一对table1和table2?
  • 你能详细说明你想要什么吗?所有其他表(table1、table2、tabke3)是否具有相同的结构和逻辑
  • 是的,完全正确。其他表(table1、table2、table3)将具有完全相同的结构和逻辑。只有表的名称会不同。
  • @JingsiXu 我已根据您的要求编辑了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-02
  • 1970-01-01
相关资源
最近更新 更多