仅当 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;

根据您的示例数据,您似乎希望在 idstate_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.