【问题标题】:DB2 for IBM i (AS400) - SQLDB2 for IBM i (AS400) - SQL
【发布时间】:2015-06-05 09:17:04
【问题描述】:

两个表 A(每日贷款交易表)和 B(每日 eod 贷款余额表)。

尝试在 DB2 AS400 中编写一个 select 语句来显示选定日期范围内的每日贷款交易、eod Loan Balance 和开始贷款余额(前一天)。

以下查询将为我提供每日贷款交易和 eod 贷款余额。但是需要一些帮助来修改下面的查询以计算所选日期范围 03/01/2015 至 03/31/2015 的起始贷款余额(截至 2015 年 2 月 28 日的余额)。

select A.*, -- daily loan transactions
       B.EOD_Loan_Balance
from A 
  inner join B 
   on A.date_id = B.date_id 
    and A.Loan_num = B.Loan_num
where a.date_id between 03/01/2015 to 03/31/2015

请注意,前一天应该是工作日,所以如果 2015 年 2 月 28 日不是工作日,那么我们需要提取前一天的 eod 余额,这应该是工作日。

任何想法都将不胜感激。

谢谢!

【问题讨论】:

  • 为了澄清,您还想选择EOD_Loan_Balance where date_id = ('2015-03-01' - 1 day)。还是日期不连续?
  • 起始贷款余额,即 2015 年 3 月 1 日的前一天 eod 余额,即('2015-03-01' - 1 天),它应该是一个工作日。如果前一天不是工作日,则必须从前一天获得 eod 余额。

标签: sql db2 ibm-midrange


【解决方案1】:

这是使用“日历”或“日期”表可以轻松完成的众多任务之一...

select D.*,
       B.EOD_Loan_Balance,
       E.EOD_Loan_Balance,
from MY_CALENDAR_TABLE C
     join daily_trans D on c.date = d.date 
     join eod_bal B on c.date - 1 day= b.date and d.loan_num = b.loan_num
     join eod_bal E on c.date = e.date and d.loan_num = e.loan_num
where c.date between 2015-03-01 and 2015-03-31
  and c.is_business_day = 1;

--编辑--
回想起来,我意识到它并不完全奏效;从头开始加入余额不会为您提供前一个营业日

幸运的是,日历表的灵活性可以帮上忙。只需在日历表中添加 PRIOR_BUSINESS_DAY 列即可。

那么SQL就变成了:

select D.*,
       B.EOD_Loan_Balance,
       E.EOD_Loan_Balance,
from MY_CALENDAR_TABLE C
     join daily_trans D on c.date = d.date
     join eod_bal B on c.prior_buisiness_day = b.date 
           and d.loan_num = b.loan_num
     join eod_bal E on c.date = e.date
           and d.loan_num = e.loan_num
where c.date between 2015-03-01 and 2015-03-31
  and c.is_business_day = 1;

【讨论】:

    【解决方案2】:

    这对你有用吗?

    select A.*, -- daily loan transactions
           B.EOD_Loan_Balance,
           C.EOD_Loan_Balance,
    from A 
      inner join B 
       on A.date_id = B.date_id 
        and A.Loan_num = B.Loan_num
      LEFT OUTER join C
       on A.Loan_num = C.Loan_num
    where a.date_id between '2015-03-01' to '2015-03-31'
    and c.date_id = CASE 
                      WHEN DAYOFWEEK('2015-03-01') = 1 THEN '2015-03-01' - 2 days 'Sunday --> Friday
                      WHEN DAYOFWEEK('2015-03-01') = 2 THEN '2015-03-01' - 3 days 'Monday --> Friday
                      ELSE                                  '2015-03-01' - 1 day ' Previous day
                    END
    

    未经测试,因为我手边没有 DB2 实例。

    编辑已修改为允许在 cmets 中提到的周末。

    【讨论】:

    • 上述规定在以下情况下不起作用: 1) 如果 C 中的 EOD 余额在前一天不存在,那么今天发生的每日交易将不会显示。为了避免这种情况,如果使用左连接,那么我们不能在 c.date_id 上应用 where 条件。 2) 如果前一天不是工作日
    • 这很好用,除非存在左外连接的目的。因为在表上使用 where 条件左外连接到其他表将用作内连接。例如:我希望看到每日交易,即使 C 中的前一个工作日余额不存在,它可以通过左外连接实现,但 C.date_id 上的 where 条件不显示每日交易。
    • 如果您有一个月的工作日放假会怎样?拥有一个预先计算好的日历表是​​处理这类问题的最佳方式。
    • @Charles,OP 没有具体说明“工作日”的定义。它甚至没有包含在原始问题中。我同意,对于严肃的业务用途,您需要一个强大而灵活的解决方案(而不是将事物硬编码到 SQL 中)。但是在这个网站上,你永远不知道你是在帮助初学者完成家庭作业,还是帮助一个专业的现实世界问题。所以,我不打算解决问题中未包含的问题。
    • @Turophile,我可以理解不考虑工作日,因为它不在原始问题中。如果 OP 会根据要求更新问题,那就太好了。但我认为学生或新专业人士,为此类问题引入日历表概念始终是正确答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多