【问题标题】:Having trouble in a PL/SQL program在 PL/SQL 程序中遇到问题
【发布时间】:2018-04-11 13:05:54
【问题描述】:

我有一个如下表(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循环来做,如果有其他更好的方法可以做到这一点,你能建议吗?

【问题讨论】:

  • 发布你目前尝试过的循环

标签: plsql price period


【解决方案1】:
  1. 您必须查看 checkin_date 和 checkout_date 是否在同一个 period_id 中。 1.1 如果是,您将价格乘​​以天数。 1.2 如果不是,您计算从 checkin_day 到周期 1 结束的天数,并乘以相应的价格,然后对 checkout_day 和下一个周期的开始执行相同的操作。

注意:我猜每个 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 和 period 的价格;遍历它并将 checkin_date 和 checkout_date 与每条记录进行比较。

最好, 米库图。

【讨论】:

    【解决方案2】:

    您可以执行以下操作以获得更简洁的代码。虽然是纯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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-23
      • 1970-01-01
      相关资源
      最近更新 更多