在Oracle中选择分组集中的最新数据

时间:2013-12-26 19:25:29

标签: sql oracle oracle11g group-by

我正在编写一个过程来查询Oracle中的一些数据并对其进行分组:

Account  Amt Due   Last payment  Last Payment Date (mm/dd/yyyy format)
1234      10.00       5.00          12/12/2013
1234      35.00       8.00          12/12/2013
3293      15.00      10.00          11/18/2013
4455       8.00       3.00          5/23/2013
4455      14.00       5.00          10/18/2013

我想对数据进行分组,因此每个帐户只有一条记录,Amt到期金额以及最后一笔付款。除非最后一个付款日期不同 - 如果日期不同,那么我只想要最后一次付款。所以我希望得到这样的结果:

Account  Amt Due   Last payment  Last Payment Date
1234      45.00      13.00          12/12/2013
3293      15.00      10.00          11/18/2013
4455      22.00       5.00          10/18/2013

我正在做类似

的事情
select Account, sum (AmtDue), sum (LastPmt), Max (LastPmtDt)
from all my tables
group by Account

但是,这并不适用于上面的最后一条记录,因为最后一笔付款仅为10月18日的5.00美元,而不是10月18日的总和。

如果我按帐户和LastPmtDt进行分组,那么我最后会得到两条记录,但我只需要每个帐户一条记录。

我有其他数据我查询,我在另一个字段上使用CASE,INSTR和LISTAGG(如果组合它们会给我这个子字符串,然后输出' Both' Both' Both' Both' Both' Both' Both' Both' Both' Both' Both&#39 39 ;;否则如果它只给我这个子串,则输出子串;否则如果它只给我另一个子串,则输出那个子串。似乎我可能需要类似的东西,但不是通过寻找特定的日期。如果日期相同,则sum(LastPmt)和max(LastPmtDt)工作正常,如果它们不相同,那么我想忽略除最近的LastPmt和LastPmtDt记录以外的所有记录。

哦,我的LastPmt和LastPmtDt字段已经是select中的case语句。它们不是我已经可以访问的字段。我正在阅读关于RANK和KEEP的其他帖子,但是要涉及这两个领域,我也需要对每个领域进行所有计算。查询所有内容,然后围绕它进行另外的查询以进行分组,求和和选择我想要的字段会更有效吗?

相关:HAVING - GROUP BY to get the latest record

有人可以就如何解决这个问题提供一些指导吗?

3 个答案:

答案 0 :(得分:2)

试试这个:

select Account, 
       sum ( Amt_Due), 
       sum (CASE WHEN Last_Payment_Date = last_dat THEN Last_payment ELSE 0 END), 
       Max (Last_Payment_Date)
from (
  SELECT t.*,
       max( Last_Payment_Date ) OVER( partition by Account ) last_dat
  FROM table1 t
)
group by Account

演示 - > http://www.sqlfiddle.com/#!4/fc650/8

答案 1 :(得分:0)

Rank是正确的想法。

试试这个

select a.Account, a.AmtDue, a.LastPmt, a.LastPmtDt from (
  select Account, sum (AmtDue) AmtDue, sum (LastPmt) LastPmt, LastPmtDt, 
    RANK() OVER (PARTITION BY Account ORDER BY LastPmtDt desc) as rnk
  from all my tables
  group by Account, LastPmtDt
  ) a
where a.rnk = 1

我没有对此进行测试,但它应该给你正确的想法。

答案 2 :(得分:0)

试试这个:

select Account, sum(AmtDue), sum(LastPmt), LastPmtDt
  from (select Account,
               AmtDue,
               LastPmt,
               LastPmtDt,
               max(LastPmtDt) over(partition by Account) MaxLastPmtDt
          from your_table) t
 where t.LastPmtDt = t.MaxLastPmtDt
 group by Account, LastPmtDt