我有一张表(pay_period)如下
pay_period
period_id list_id start_date end_date price
1 100 2017-01-01 2017-08-31 100
2 100 2017-09-01 2017-12-31 110
3 101 2017-01-01 2017-08-31 75
现在我有list_id,checkin_date,checkout_date
list_id 100
checkin_date 2017-08-25
checkout_date 2017-09-10
我需要计算从登记日期到结帐日期的清单价格。 因此计算应该是
7 * 100 + 10 * 110
我想用for循环来做,如果还有其他更好的方法可以做,你能建议吗?
答案 0 :(得分:0)
注意:我猜每个list_id的价格可能超过2个。例如:
period_id list_id start_date end_date price
1 100 2017-01-01 2017-04-30 100
2 100 2017-05-01 2017-09-30 110
3 100 2017-10-01 2017-12-31 120
4 101 2017-01-01 2017-08-31 75
和计算期间:
list_id 100
checkin_date 2017-03-01
checkout_date 2017-11-10
在这种情况下,是的,解决方案是让CURSOR保持list_id和期间的价格;循环遍历它并将checkin_date和checkout_date与每条记录进行比较。
最佳, Mikcutu。
答案 1 :(得分:0)
您可以执行以下操作以获得更清晰的代码。虽然它纯粹是sql,但我正在使用一个函数来使代码更好地理解。
创建一个通用function
,可以获取2个不同日期范围内的重叠天数。
CREATE OR REPLACE FUNCTION fn_count_range
( p_start_date1 IN DATE,
p_end_date1 IN DATE,
p_start_date2 IN DATE,
p_end_date2 IN DATE ) RETURN NUMBER AS
v_days NUMBER;
BEGIN
IF p_end_date1 < p_start_date1 OR p_end_date2 < p_start_date2 THEN
RETURN 0;
END IF;
SELECT COUNT(*) INTO v_days
FROM (
(SELECT p_start_date1 + LEVEL - 1
FROM dual CONNECT BY LEVEL <= p_end_date1 - p_start_date1 + 1 ) INTERSECT
(SELECT p_start_date2 + LEVEL - 1
FROM dual CONNECT BY LEVEL <= p_end_date2 - p_start_date2 + 1 ) );
RETURN v_days;
END;
/
现在,简化了计算总价的查询。
WITH lists ( list_id,
checkin_date,
checkout_date) AS
( SELECT 100,
TO_DATE('2017-08-25','YYYY-MM-DD'),
TO_DATE('2017-09-10','YYYY-MM-DD')
FROM dual) --Not required if you have a lists table.
SELECT l.list_id,
SUM(fn_count_range(start_date,end_date,checkin_date,checkout_date) * price) total_price
FROM pay_period p
JOIN lists l ON p.list_id = l.list_id
GROUP BY l.list_id;