简体   繁体   中英

SQL: Get latest record grouped by multiple columns in Oracle DB

I have a table SITE_SETTINGS like the following:

SITE_ID   SETTINGS_CODE   UPDATE_TS   OTHER_SETTINGS1   OTHER_SETTINGS2
1         CODE1           21-JAN-17   S1                S2
1         CODE1           23-JAN-17   S3                S4
1         CODE2           14-JAN-17   S1                S4
1         CODE2           18-JAN-17   S1                S3
1         CODE2           21-JAN-17   S1                S2
1         CODE3           04-FEB-17   S8                S9
2         CODE1           21-MAR-17   S1                S2
2         CODE2           21-JAN-17   S2                S5
2         CODE1           21-MAR-17   S1                S5
2         CODE2           10-MAR-17   S1                S5
2         CODE3           10-JAN-17   S1                S5

These are multiple SITES, each with 3 different types of SETTINGS_CODE. I need the latest record for each settings_code for all the sites. Something like this:

SITE_ID   SETTINGS_CODE   UPDATE_TS   OTHER_SETTINGS1   OTHER_SETTINGS2
1         CODE1           23-JAN-17   S3                S4
1         CODE2           21-JAN-17   S1                S2
1         CODE3           04-FEB-17   S8                S9
2         CODE1           21-MAR-17   S1                S2
2         CODE2           10-MAR-17   S1                S5
2         CODE3           10-JAN-17   S1                S5

I am trying to do a join on the table with itself but it gives me duplicate records. For example, I get multiple identical records for CODE1 for SITE_ID=1. This is what I have tried:

        select t.SITE_ID, t.SETTINGS_CODE, t.OTHER_SETTINGS1, t.OTHER_SETTINGS2, t.UPDATE_TS
        from SITE_SETTINGS t
        inner join (
            select SITE_ID, SETTINGS_CODE, max(UPDATE_TS) as MaxDate
            from SITE_SETTINGS
            group by SITE_ID, SETTINGS_CODE
            order by SITE_ID, SETTINGS_CODE
        ) tm on t.SITE_ID = tm.SITE_ID and t.SETTINGS_CODE=tm.SETTINGS_CODE and t.UPDATE_TS = tm.MaxDate

I think the issue I am having is inability to group by multiple columns. Is there any way to get data without the duplicates?

You can do this using row_number() window function:

select * from (
    select SITE_SETTINGS.*, row_number() over(partition by SITE_ID,   SETTINGS_CODE order by UPDATE_TS desc) as rn 
    from SITE_SETTINGS
) t
where rn = 1
SELECT SITE_ID,
       SETTINGS_CODE,
       LATEST_UPDATE_TS,
       OTHER_SETTINGS1,
       OTHER_SETTINGS2 
  FROM 
    (
      SELECT SITE_ID,
             SETTINGS_CODE,
             UPDATE_TS,
             MAX( UPDATE_TS ) OVER ( PARTITION BY SITE_ID,SETTINGS_CODE ORDER BY 
             UPDATE_TS ) AS LATEST_UPDATE_TS,
             OTHER_SETTINGS1,
             OTHER_SETTINGS2   
        FROM SITE_SETTINGS
    )
WHERE UPDATE_TS = LATEST_UPDATE_TS;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM