创建一个计算每月总收入的 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 中,您将如何使用两个日期列计算每月和每日总计?