【问题标题】:How to apply RANK() only if the JOIN condition returns a matching record?仅当 JOIN 条件返回匹配记录时,如何应用 RANK()?
【发布时间】:2021-08-27 06:53:22
【问题描述】:

我在 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 的州代码。如果有多个匹配项,则根据 Expiry_Dates 选择/排列记录。

【问题讨论】:

    标签: sql oracle oracle12c


    【解决方案1】:

    你可以这样:

    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
    

    【讨论】:

      【解决方案2】:

      给你:

      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
      

      【讨论】:

        【解决方案3】:

        如果您想要两个表中的列,那么这是横向连接的方便位置。根据您的描述,您希望:

        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 是一个 dbfiddle。

        【讨论】:

          猜你喜欢
          • 2021-01-07
          • 2022-01-14
          • 1970-01-01
          • 2011-09-12
          • 1970-01-01
          • 1970-01-01
          • 2020-12-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多