Oracle双重选择问题

时间:2017-04-12 17:08:35

标签: oracle select rownum

所以我在Oracle上有这两个表:

客户端

cl_id  cl_name
1      John
2      Maria

PAYMENTS

pa_id  pa_date        pa_status   cl_id
1      2017-01-01     1           1
2      2017-01-01     1           2
3      2017-02-01     1           1
4      2017-02-01     1           2
5      2017-03-01     0           1
6      2017-03-01     1           2

我需要一个select statemant,它为我提供客户ID,NAME和他最后付款的状态。所以我选择的最终结果应该是:

cl_id  cl_name  pa_status
1      John     0
2      Maria    1

这是有效的客户端选择:

select cl_id, cl_name from CLIENT;

这是PAYMENT选择的最后一个状态:

select * from ( select pa_status from PAYMENT ORDER BY PA_DATE DESC) where rownum = 1;

所以现在,我需要让它们一起工作。我尝试了两种不起作用的方法:

select cl_id, cl_name, (select * from ( select pa_status from PAYMENT ORDER BY PA_DATE DESC) where rownum = 1 and PAYMENT.cl_id = CLIENT.CL_ID) as last_status from CLIENT;

错误:标识符无效

和此:

select cl_id, cl_name, (select * from ( select pa_status from PAYMENT ORDER BY PA_DATE DESC) where rownum = 1 ) as last_status from CLIENT;

不会给我任何错误,但只显示最后一条记录的John的最后状态:

cl_id cl_name  last_status
1     John     0
2     Maria    0

任何人都可以给我一个提示吗?

由于

4 个答案:

答案 0 :(得分:1)

你需要使用分析功能。 通过这种功能,您可以将数据拆分为某些组,并根据需要对每个组的数据进行排名。

在你的情况下:

Select * from (
Select id, name, status, row_number () over (partition by      p.cl_id order by p.pa_date desc) as rw
From client c join payments p on p.cl_id = c.cl_id)
Inn where inn.rw = 1;

答案 1 :(得分:0)

这将获取客户端的最大日期 然后获得该日期的最高付款ID。

with max_date as (
      select max(date) as max_date, cl_id from payments group by cl_id
)
select c.cl_id, c.cl_name, p.pa_sttus from client c
join payments p
on c.cl_id = p.cl_id
where p.pa_id = (select max(p2.pa_id) from payments p2
                  join max_date md
                  on p2.cl_id = md.cl_id
                  where p.cl_id = p2.cl_id 
                  and p2.pa_date = md.max_date
                  )

答案 2 :(得分:0)

首先从每个clientid获取最大日期。

Select cl_id, max(pa_date) as pa_date from PAYMENTS group by cl_id

现在你拿到你的客户端表并加入上面的子查询

select c.cl_id, c.cl_name,
(select pa_status from PAYMENT t where t.pa_date=p.pa_date and t.cl_id=p.cl_id)
from CLIENT c join (Select cl_id, max(pa_date) as pa_date from PAYMENTS group by cl_id) p on p.cl_id=c.cl_id

答案 3 :(得分:0)

您可以在此处使用Oracle KEEP LAST

select cl_id, c.cl_name, last_payment.status
from client
join
(
  select 
    cl_id,
    max(pa_status) keep (dense_rank last order by pa_date) as status
  from payments
  group by cl_id
) last_payment using (cl_id);

(如果您想要包含未付款的客户,请将联接更改为LEFT OUTER JOIN。)