Oracle 双 select 问题
Oracle double select issue
所以我在 Oracle 上有这两个表:
客户
cl_id cl_name
1 John
2 Maria
付款
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 语句,它可以提供客户 ID、姓名和他 最后 付款的状态。所以我的 select 的最终结果应该是:
cl_id cl_name pa_status
1 John 0
2 Maria 1
这是有效的客户端 select:
select cl_id, cl_name from CLIENT;
这是 PAYMENT select 有效的最后状态:
select * from (
select pa_status from PAYMENT ORDER BY PA_DATE DESC)
where rownum = 1;
所以现在,我需要让它们协同工作。我尝试了 2 种无效的方法:
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
谁能给我提示?
谢谢
这会获取客户的最大日期
然后获取该日期的最高付款 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
)
您需要使用解析函数。
这种功能可以让你把你的数据分成一些组,然后按照你的意愿对每个组的数据进行排序。
你的情况:
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;
首先为每个clientid 取最大值。
Select cl_id, max(pa_date) as pa_date from PAYMENTS group by cl_id
现在你带你的客户 table 并加入上面的子查询
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
您可以在此处使用 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
。)
所以我在 Oracle 上有这两个表:
客户
cl_id cl_name
1 John
2 Maria
付款
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 语句,它可以提供客户 ID、姓名和他 最后 付款的状态。所以我的 select 的最终结果应该是:
cl_id cl_name pa_status
1 John 0
2 Maria 1
这是有效的客户端 select:
select cl_id, cl_name from CLIENT;
这是 PAYMENT select 有效的最后状态:
select * from (
select pa_status from PAYMENT ORDER BY PA_DATE DESC)
where rownum = 1;
所以现在,我需要让它们协同工作。我尝试了 2 种无效的方法:
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
谁能给我提示?
谢谢
这会获取客户的最大日期 然后获取该日期的最高付款 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
)
您需要使用解析函数。 这种功能可以让你把你的数据分成一些组,然后按照你的意愿对每个组的数据进行排序。
你的情况:
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;
首先为每个clientid 取最大值。
Select cl_id, max(pa_date) as pa_date from PAYMENTS group by cl_id
现在你带你的客户 table 并加入上面的子查询
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
您可以在此处使用 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
。)