最大日期功能可提供多个记录

时间:2019-05-31 14:45:01

标签: sql oracle

我有3个表:订单,客户和发票。我需要获取每个客户的最新发票编号。

我在订单日期使用max功能,然后按确认或发货状态的客户编号和发票编号分组。

  select max(o.order_date), c.customer_number, i.invoice_number
  from orders o , invoices i , customer c
  where o.order_oid = i.order_oid
  and c.customer_oid = i.customer_oid
  and o.status_oid in (  4,6)
  group by c.customer_number, i.invoice_number;

我收到重复的记录,例如:

 Date       cust_num    invc#
 1/22/2018   479         I128
 4/23/2018   479         I287
 5/18/2018   479         I433

它应该只返回了我的最后一条记录。我在做什么错了?

3 个答案:

答案 0 :(得分:0)

您需要max(invoice_number)以避免获得每张发票的记录

答案 1 :(得分:0)

根据您的描述和评论,您可能想要:

select max(o.order_date), c.customer_number,
  max(i.invoice_number) keep (dense_rank last order by o.order_date) as invoice_number
from orders o , invoices i , customer c
where o.order_oid = i.order_oid
and c.customer_oid = i.customer_oid
and o.status_oid in (  4,6)
group by c.customer_number;

group by不再包含发票编号;而是使用last找到基于日期的最后发票编号。

如果发票编号严格按照日期顺序和固定长度进行,则可以执行以下操作:

select max(o.order_date), c.customer_number, max(i.invoice_number) as invoice_number

但是,如果有可能将发票I999更改为I1000,则将它们作为字符串进行排序是不安全的,因为-字符串“ I1000”将在“ I999”之前进行排序。


无关,但是您可能要考虑采用现代联接语法:

select max(o.order_date), c.customer_number,
  max(i.invoice_number) keep (dense_rank last order by o.order_date) as invoice_number
from orders o
join invoices i on i.order_oid = o.order_oid
join customer c on c.customer_oid = i.customer_oid
where o.status_oid in (4, 6)
group by c.customer_number;

答案 2 :(得分:0)

您可以使用row_number()窗口分析功能

select order_date, customer_number, invoice_number
  from   
 (
  select o.order_date, c.customer_number, i.invoice_number, 
         row_number() over (partition by c.customer_number order by o.order_date desc) as rn             
    from orders o 
    join invoices i on o.order_oid = i.order_oid
    join customer c on c.customer_oid = i.customer_oid 
   where o.status_oid in (4,6)
  )
 where rn = 1;

P.S。 :当然,要放弃对查询使用老式逗号分隔的联接