Postgres自定义函数数据分摊实战

Postgres创建自定义函数分摊费用实战

需求背景

因在项目交付过程中,客户需将 某个科室、按月、将总费用、及其他不同类型的费用分摊 并增加到指定的科室里面去,为了防止后续分摊科室发生变动,我们可将部分参数定为入参从而达到自定义函数的可通用性。

建表测试

create table income_summary_month
(
    id             serial not null
        constraint income_summary_month_pk
            primary key,
    stat_date_id   integer,
    stat_date      timestamp,
    dept_code      integer,
    dept_name      varchar(50),
    visit_type     varchar(20),
    total_cost     numeric(12, 4),
    drug_cost      numeric(12, 4),
    material_cost  numeric(12, 4),
    check_lab_cost numeric(12, 4)
);
comment on table income_summary_month is '医疗运营月汇总测试表';
alter table income_summary_month
    owner to postgres;

测试数据如下


---测试数据
INSERT INTO public.income_summary_month (id, stat_date_id, stat_date, dept_code, dept_name, visit_type, total_cost, drug_cost, material_cost, check_lab_cost) VALUES (11144, null, '2023-11-01 00:00:00.000000', 9412, '泌尿外科一区', '住院', 1451199.0100, 183348.6100, 224231.9200, 323255.2000);
INSERT INTO public.income_summary_month (id, stat_date_id, stat_date, dept_code, dept_name, visit_type, total_cost, drug_cost, material_cost, check_lab_cost) VALUES (11107, null, '2023-11-01 00:00:00.000000', 9413, '泌尿外科二区', '住院', 1888720.2500, 229872.5800, 349544.0800, 322582.0000);
INSERT INTO public.income_summary_month (id, stat_date_id, stat_date, dept_code, dept_name, visit_type, total_cost, drug_cost, material_cost, check_lab_cost) VALUES (11103, null, '2023-11-01 00:00:00.000000', 9013, '儿科三区', '住院', null, null, null, null);
INSERT INTO public.income_summary_month (id, stat_date_id, stat_date, dept_code, dept_name, visit_type, total_cost, drug_cost, material_cost, check_lab_cost) VALUES (11175, null, '2023-11-01 00:00:00.000000', 1015, '泌尿外科门诊', '门诊', 498995.9500, 221168.9100, 12126.4400, 165380.6000);
INSERT INTO public.income_summary_month (id, stat_date_id, stat_date, dept_code, dept_name, visit_type, total_cost, drug_cost, material_cost, check_lab_cost) VALUES (11244, null, '2023-11-01 00:00:00.000000', 1088, '眼科门诊', '门诊', 362039.3600, 101187.7600, 144.0000, 182412.6000);
INSERT INTO public.income_summary_month (id, stat_date_id, stat_date, dept_code, dept_name, visit_type, total_cost, drug_cost, material_cost, check_lab_cost) VALUES (11155, null, '2023-11-01 00:00:00.000000', 1012, '心胸外科门诊', '门诊', 120930.8000, 9319.8600, 642.9400, 105045.0000);
INSERT INTO public.income_summary_month (id, stat_date_id, stat_date, dept_code, dept_name, visit_type, total_cost, drug_cost, material_cost, check_lab_cost) VALUES (11133, null, '2023-11-01 00:00:00.000000', 1020, '儿科一区', '住院', 1138973.5600, 251975.8100, 9877.7500, 473203.4000);
INSERT INTO public.income_summary_month (id, stat_date_id, stat_date, dept_code, dept_name, visit_type, total_cost, drug_cost, material_cost, check_lab_cost) VALUES (11132, null, '2023-11-01 00:00:00.000000', 1019, '产科二区', '住院', 1430968.1300, 278930.4100, 79588.3200, 303889.0000);
INSERT INTO public.income_summary_month (id, stat_date_id, stat_date, dept_code, dept_name, visit_type, total_cost, drug_cost, material_cost, check_lab_cost) VALUES (11094, null, '2023-11-01 00:00:00.000000', 9011, '产科一区', '住院', 1275625.4000, 249954.9400, 71193.8600, 300104.0000);

在这里插入图片描述

创建函数

create function avg_dept_fee(dept_ids    integer,--定义科室代码字段维度
                             avg_dept    integer, --被均分的科室
                             avg_num     integer, --被均分为几分
                             fee_type    character varying,--定于不同的费用类型
                             starttime   timestamp without time zone,--定义时间维度
                             dept_codes  integer[]) returns numeric--定义科室代码
    language plpgsql
as
$$
BEGIN
    IF (dept_ids = any (dept_codes) and fee_type = 'total1') then
        return (
            select coalesce(total_cost, 0) / avg_num
            from std_dws_hos_workload_income_summary_month
            where stat_date = starttime
              and dept_id in (avg_dept)
        );
    ELSEIF (dept_ids = any (dept_codes) and fee_type = 'drug1') then
        return (
            select coalesce(drug_cost, 0) / avg_num
            from std_dws_hos_workload_income_summary_month
            where stat_date = starttime
              and dept_id in (avg_dept)
        );
    ELSEIF (dept_ids = any (dept_codes) and fee_type = 'check1') then
        return (
            select coalesce(check_lab_cost, 0) / avg_num
            from std_dws_hos_workload_income_summary_month
            where stat_date = starttime
              and dept_id in (avg_dept)
        );
    ELSE
        RETURN 0;
    END IF;
END
$$;

alter function avg_dept_fee(integer, integer, integer, varchar, timestamp, integer[]) owner to postgres;

函数应用

select
dept_code,dept_name,
total_cost,
avg_dept_fee ( dept_code,1088,2,'total1', stat_date,array [1019,9011] ),
total_cost+  avg_dept_fee(dept_code,1088,
    2,'total1', stat_date,array [1019,9011])          as sum_total_cost,
drug_cost,
avg_dept_fee ( dept_code,1088,2,'drug1', stat_date,array [1019,9011] ),
drug_cost+  avg_dept_fee(dept_code,1088,
    2,'drug1', stat_date,array [1019,9011])          as sum_drug_cost,
check_lab_cost,
avg_dept_fee ( dept_code,1088,2,'check1', stat_date,array [1019,9011] ),
check_lab_cost+  avg_dept_fee(dept_code,1088,
    2,'check1', stat_date,array [1019,9011])          as sum_check_lab_cost
from  income_summary_month a
where dept_code in ('9412','9413','1015','1088','1019','9011');

在这里插入图片描述

总结:虽然功能很简单,甚至还有很多其他办法可以实现,但是我希望能通过此自定义函数,能做到如下几点:
1)让看到的筒靴、朋友、前辈能不经意间 温习下函数语法
2)能更好的定一些函数解决通用性问题
3)把一些认为好、有价值的分享出来

  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

项目实战哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值