创建一个计算每月总收入的 PL/SQL 过程。总计必须按月打印

Posted

技术标签:

【中文标题】创建一个计算每月总收入的 PL/SQL 过程。总计必须按月打印【英文标题】:Create a PL/SQL procedure that calculate total monthly income. Total must be printed by month 【发布时间】:2018-12-01 16:29:01 【问题描述】:

编写一个程序,计算并显示所有酒店所有来源的总收入。总计必须按月打印,并且每个月按事件和服务类型打印。包括折扣。(如果预订日期是预订开始日期前 2 个月,则可享受 10% 的折扣)。

这些表格是:

酒店表有:

Hotel_id, hotel_name, Hotel_city, Hotel_state, Hotel_zip,Hotel_phone

预订表有:

Reservation_id, Hotel_id, Room_num, Service_id, Guest_name, Reservation_date, Reservation_start_date, Reservation_end_date, cancelation_date, Num_of_guest, event_type

房间桌子有:

Room_num, Hotel_id, Room_type, Room_capacity, Room_cost

服务表有:

service_id, Service_type, Service_cost

这是我试过的,但我想写成程序形式;我怎么做?请帮忙。谢谢

select month (Reservation_end_date) as , event_type,
sum(case when days>= 2 then cost- (cost/100)* 10
else cost) as total_cost)



((select distinct reservation.hotel_id,reservation_date, reservation_start_date,
reservation_end_date, event_type, room.room_type as R_type ,room_cost as R_cost,
months_between(reservation_start_date,reservation_date)as months
from reservation, room
where reservation.hotel_id = room.hotel_id;)

union

 (select hotel_name, reservation_date, reservation_start_date,
reservation_end_date, event_type, services_type, services_cost as cost,
months_between(reservation_start_date,reservation_date)as month
from reservation,service, hotel
where reservation.services_id = service.services_id 
and reservation.hotel_id = hotel.hotel_id;))

group by month(reservation_end_date),event_type;

【问题讨论】:

有4个表(我们不知道它们之间是什么关系);您发布了(无效且未格式化,难以阅读)查询。我建议您编写一个按原样 工作的查询。然后将其转换为 PL/SQL 是一项简单的任务 - 您必须选择它返回 INTO 变量的值并对它们进行操作(使用 DBMS_OUTPUT.PUT_LINE 显示它们是一个选项)。 【参考方案1】:

第一步是正确获取基本查询。

要将一组日期合并到它们的常用月份中,请使用trunc(date_col, 'mm')。大概房间费用和服务费用应该按每晚计算。 要计算晚数,只需从结束日期减去开始日期即可。

此查询应该产生正确的结果(您陈述的业务规则不完整,因此很难确定)。就像您发布的代码一样,它有子查询来计算每个房间预订和每个服务预订的成本。这些在外部查询中聚合:

select to_char(r_month, 'YYYY-MON') as rpt_month
       , event_type
       , service_type
       , sum ( (r_cost - r_discount ) * no_of_nights ) as tot_cost
from (      
    select trunc(r.reservation_end_date , 'mm') as r_month
           , r.event_type
           , cast(null as varchar2(10)) as service_type
           , rm.room_cost as r_cost
           , case when months_between (r.reservation_start_date, r.reservation_date) >= 2
              then rm.room_cost * 0.1 
              else 0 end as r_discount 
            , (r.reservation_end_date - r.reservation_start_date ) as no_of_nights
    from  reservation r
          join room rm
              on ( r.room_num = rm.room_num  
              and r.hotel_id = rm.hotel_id )
    union all
    select trunc(r.reservation_end_date , 'mon') as r_month
           , r.event_type
           , sv.service_type
           , sv.service_cost  as r_cost
           , case when months_between (r.reservation_start_date, r.reservation_date) >= 2
              then sv.service_cost * 0.1 
              else 0 end as r_discount 
           , (r.reservation_end_date - r.reservation_start_date ) as no_of_nights
    from  reservation r
          join service sv
              on ( r.service_id = sv.service_id )
    )  
group by r_month
       , event_type
       , service_type
order by r_month
       , event_type
       , service_type      
;

第二步是把这个放到一个过程中。同样,您的要求是模糊的:程序是否应该采用任何参数?输出应该是什么格式?由于业务领域(酒店预订)和问题的格式(“编写一个程序...”)这似乎是一个家庭作业,所以这是对的最简单解释显示”。它使用dbms_output 例程打印到屏幕上,并使用rpad()lpad() 提供一个漂亮的布局(显然间距可能很不稳定,因为您没有提供各个列的数据类型)。

create or replace procedure display_monthly_reservations as
begin
    << heading >>
    dbms_output.put(rpad('MONTH', 8)); 
    dbms_output.put( rpad('EVENT_TYPE' , 20 ) || ' ');  
    dbms_output.put( rpad('SERVICE_TYPE', 20 ) || ' ');  
    dbms_output.put_line('TOTAL_COST'); 

    << per_line >>
    for r in (
         << insert the query here >> 
    ) loop
        dbms_output.put(r.rpt_month || ' '); 
        dbms_output.put( rpad(r.event_type , 20 ) || ' ');  
        dbms_output.put( rpad(r.service_type , 20 ) || ' ');  
        dbms_output.put_line( lpad(to_char(r.tot_cost , '9999999.99'), 10 ) );   
    end loop per_line;

end display_monthly_reservations;
/ 

【讨论】:

以上是关于创建一个计算每月总收入的 PL/SQL 过程。总计必须按月打印的主要内容,如果未能解决你的问题,请参考以下文章

使用两个过程用 OUT 和 IN 参数进行简单计算,PL/SQL Oracle

在 BigQuery 中,您将如何使用两个日期列计算每月和每日总计?

从 PL/SQL 中的过程返回值数组

使用自定义类型参数创建一个过程。 PL/SQL

PL/SQL: SQL 语句被忽略 - 创建一个过程得到编译错误

PL/SQL 存储过程创建表