仅当 JOIN 条件 returns 匹配记录时,如何应用 RANK()?
How to apply RANK() only if the JOIN condition returns a matching record?
我正在努力处理 Oracle SQL 查询,我只想在有匹配记录时应用排名。这是我的数据:-
Table 1:
ID State_Code
1 NY
2 DC
3 AL
Table 2:
ID EXPIRY_DATE STATE_CODE X_CODE
1 30-DEC-21 NY ABC
1 30-JUN-21 NY XYZ
2 30-DEC-21 DC SQL
2 30-JUN-21 AZ DEF
3 30-JUN-21 AK PQR
RESULT:
ID STATE_CODE X_CODE
1 NY ABC
2 DC SQL
3 AL (null)
我想加入基于 ID 的州代码。如果有多个匹配,则 choose/rank 记录基于 Expiry_Dates.
你可以这样做:
WITH table1 (id, state_code) AS
(
SELECT 1, 'NY' FROM DUAL UNION ALL
SELECT 2, 'DC' FROM DUAL UNION ALL
SELECT 3, 'AL' FROM DUAL
), table2 (id,expiry_date,state_code,x_code)
AS
(
SELECT 1, TO_DATE('30-DEC-21','DD-MON-YY'), 'NY','ABC' FROM DUAL UNION ALL
SELECT 1, TO_DATE('30-JUN-21','DD-MON-YY'), 'NY','XYZ' FROM DUAL UNION ALL
SELECT 2, TO_DATE('30-DEC-21','DD-MON-YY'), 'DC','SQL' FROM DUAL UNION ALL
SELECT 2, TO_DATE('30-JUN-21','DD-MON-YY'), 'AZ','DEF' FROM DUAL UNION ALL
SELECT 3, TO_DATE('30-JUN-21','DD-MON-YY'), 'AK','PQR' FROM DUAL
), table2_ranked (id,expiry_date,state_code,x_code, rnk) AS
(
SELECT id,expiry_date,state_code,x_code, RANK() OVER (ORDER BY expiry_date DESC)
FROM table2
)
SELECT t1.id, t1.state_code, t2.x_code
FROM table1 t1
LEFT OUTER JOIN table2_ranked t2 ON t1.state_code = t2.state_code AND t2.rnk = 1
给你:
Select * from (
Select a.ID,a.State_Code,b.X_CODE ,
row_number() over(partition by a.id,a.state_code order by TO_DATE(b.expiry_date,'DD-MON-YY') desc) as rnum
from Tab1 a left join tab2 b on a.id = b.id and a.state_code = b.state_code
) c where rnum = 1
如果您需要两个表中的列,那么这是横向连接的方便位置。根据您的描述,您需要:
select t1.*, t2.x_code
from table1 t1 cross join lateral
(select t2.*
from table2 t2
where t2.id = t1.id
order by expiry_date desc
fetch first 1 row only
) t2;
根据您的示例数据,您似乎希望在 id
和 state_code
上进行匹配:
select t1.*, t2.x_code
from table1 t1 left join lateral
(select t2.*
from table2 t2
where t2.id = t1.id and t2.state_code = t1.state_code
order by expiry_date desc
fetch first 1 row only
) t2
on 1=1;
Here 是一个 db<>fiddle.
我正在努力处理 Oracle SQL 查询,我只想在有匹配记录时应用排名。这是我的数据:-
Table 1:
ID State_Code
1 NY
2 DC
3 AL
Table 2:
ID EXPIRY_DATE STATE_CODE X_CODE
1 30-DEC-21 NY ABC
1 30-JUN-21 NY XYZ
2 30-DEC-21 DC SQL
2 30-JUN-21 AZ DEF
3 30-JUN-21 AK PQR
RESULT:
ID STATE_CODE X_CODE
1 NY ABC
2 DC SQL
3 AL (null)
我想加入基于 ID 的州代码。如果有多个匹配,则 choose/rank 记录基于 Expiry_Dates.
你可以这样做:
WITH table1 (id, state_code) AS
(
SELECT 1, 'NY' FROM DUAL UNION ALL
SELECT 2, 'DC' FROM DUAL UNION ALL
SELECT 3, 'AL' FROM DUAL
), table2 (id,expiry_date,state_code,x_code)
AS
(
SELECT 1, TO_DATE('30-DEC-21','DD-MON-YY'), 'NY','ABC' FROM DUAL UNION ALL
SELECT 1, TO_DATE('30-JUN-21','DD-MON-YY'), 'NY','XYZ' FROM DUAL UNION ALL
SELECT 2, TO_DATE('30-DEC-21','DD-MON-YY'), 'DC','SQL' FROM DUAL UNION ALL
SELECT 2, TO_DATE('30-JUN-21','DD-MON-YY'), 'AZ','DEF' FROM DUAL UNION ALL
SELECT 3, TO_DATE('30-JUN-21','DD-MON-YY'), 'AK','PQR' FROM DUAL
), table2_ranked (id,expiry_date,state_code,x_code, rnk) AS
(
SELECT id,expiry_date,state_code,x_code, RANK() OVER (ORDER BY expiry_date DESC)
FROM table2
)
SELECT t1.id, t1.state_code, t2.x_code
FROM table1 t1
LEFT OUTER JOIN table2_ranked t2 ON t1.state_code = t2.state_code AND t2.rnk = 1
给你:
Select * from (
Select a.ID,a.State_Code,b.X_CODE ,
row_number() over(partition by a.id,a.state_code order by TO_DATE(b.expiry_date,'DD-MON-YY') desc) as rnum
from Tab1 a left join tab2 b on a.id = b.id and a.state_code = b.state_code
) c where rnum = 1
如果您需要两个表中的列,那么这是横向连接的方便位置。根据您的描述,您需要:
select t1.*, t2.x_code
from table1 t1 cross join lateral
(select t2.*
from table2 t2
where t2.id = t1.id
order by expiry_date desc
fetch first 1 row only
) t2;
根据您的示例数据,您似乎希望在 id
和 state_code
上进行匹配:
select t1.*, t2.x_code
from table1 t1 left join lateral
(select t2.*
from table2 t2
where t2.id = t1.id and t2.state_code = t1.state_code
order by expiry_date desc
fetch first 1 row only
) t2
on 1=1;
Here 是一个 db<>fiddle.