根据另一个SQL中的最近日期返回表中的值

时间:2018-08-06 13:34:16

标签: sql oracle

如果标题不明确,我深表歉意,但我想不出一种更好的方法来阐明目标。

我有两个表:AcctProdHist phAcctBalHist bh我分别为ph和bh别名。 AcctProdHist具有一个帐户及其productdate的产品历史记录。 AcctBalHist包含帐户余额的历史记录(按日期更改的balancedate)。

我正在尝试在balance中最接近AcctBalHist的{​​{1}}的{​​{1}}中找到balancedate的{​​{1}}。有两种情况:

  • ProductDate在2个BalanceDate之间,所以我需要两个日期中较小的那个余额
  • ProductDate小于最小值(BalanceDate)

这是我的代码,用于合并两个表并获取完整的余额历史记录:

productdate

以下是结果:

AcctProdHist

在这种情况下,我想要的select ph.acctnbr, ph.product, ph.productdate, bh.balancedate, bh.balance from AcctProdHist ph, AcctBalHist bh where ((ph.acctnbr = bh.acctnbr(+))) and ph.acctnbr in (12345,67890) 12345的ACCTNBR Product ProductDate BalanceDate Balance 12345 BYBU 7/16/2018 8/1/2018 550 12345 BYBU 7/16/2018 7/31/2018 510 12345 BYBU 7/16/2018 7/12/2018 500 12345 BYBU 7/16/2018 7/11/2018 460 12345 BYBU 7/16/2018 7/2/2018 450 67890 ABAU 7/20/2018 8/5/2018 103 67890 ABAU 7/20/2018 8/1/2018 102 67890 ABAU 7/20/2018 7/31/2018 101 67890 ABAU 7/20/2018 7/22/2018 100 是500。我想要的Balance 67890的ACCTNBR是100。

我猜我将不得不做一个UNION查询,因为我正在处理两种不同的情况,但是我什至不知道从哪里开始。

谢谢!

编辑:从各个表中添加示例数据。

Balance

ACCTNBR

AcctProdHist

ACCTNBR Product ProductDate InactiveDate
12345   ATRU    5/1/2016    7/16/2018
12345   BYBU    7/16/2018   
67890   ABAU    7/20/2018   

1 个答案:

答案 0 :(得分:1)

您必须对行进行排名。为此,请使用ROW_NUMBER,以提供最接近的余额记录#1:

select
  acctnbr, 
  product,
  productdate,
  balancedate,
  balance,
from
(
  select
    ph.acctnbr, 
    ph.product,
    ph.productdate,
    bh.balancedate,
    bh.balance,
    row_number() over (partition by ph.acctnbr
                       order by case when ph.productdate >= bh.balancedate then 1 else 2 end,
                                abs(ph.productdate - bh.balancedate)
                      ) as rn
  from AcctProdHist ph
  left join AcctBalHist bh on bh.acctnbr = ph.acctnbr
  where ph.acctnbr in (12345,67890)
)
where rn = 1
order by acctnbr;