Home > Back-end >  In Oracle SQL, How to query to extract latest date values without missing out values from join table
In Oracle SQL, How to query to extract latest date values without missing out values from join table

Time:01-13

I have two different tables in DB, SR table and Quotestable.

SR Table

Quotes_table

I have done left join both the table in the below query,

Select 
sr.sr#, sr.sub_status, sq.quotes_status, sr.Equipment_status
from svcops_emea.s_sr sr
left join svcops_emea.s_quotes sq on sq.sr# = sr.sr#
Where s.srtype = 'Repair';

I'm getting the extracts with the duplicates because for the same SR(1-5676068874) there is two different quote_status(Quote-Cancelled, Quote-Accepted)

Now I changed my query below, I'm getting unique data based on the latest 'created' date from the Quotes table but in extract, it's missing SRs(1-8376068836) because it's not present in the Quotes table.

Select sr.sr#, sr.sub_status, sq.quotes_status, sr.Equipment_status 
from svcops_emea.s_sr sr 
left join svcops_emea.s_quotes sq on sq.sr# = sr.sr# 
inner join 
(
  Select sr#, max(Created) as maxdate 
  from svcops_emea.s_quotes 
  group by sr#
) tm on sq.sr# = tm.sr# and sq.Created = tm.maxdate and sq.sr# = sr.sr# 
Where s.srtype = 'Repair'

Could anyone please help me to query this condition where I can get the unique data based on a date without missing out on any SRs from SR Table?

CodePudding user response:

If you rank rows in S_QUOTES per CREATED date value in descending order per each SR#, you can then outer-join that result to the S_SR table.

See comments within code. The 1st part of query represents sample data; query begins at line #13.

SQL> with
  2  s_sr (sr#, sub_status, equipment_status) as
  3    (select '1-7576068874', null        , 'System running' from dual union all
  4     select '1-5676068874', 'In Process', 'System down'    from dual union all
  5     select '1-8376068836', 'In Process', 'System down'    from dual
  6    ),
  7  s_quotes (sr#, quotes_status, created) as
  8    (select '1-7576068874', 'Cancel'         , date '2021-08-03' from dual union all
  9     select '1-7576068874', 'Open'           , date '2021-08-04' from dual union all
 10     select '1-5676068874', 'Quote-Cancelled', date '2021-02-03' from dual union all
 11     select '1-5676068874', 'Quote-Cancelled', date '2021-02-22' from dual
 12    ),

 13  t_quotes as
 14    -- rank S_QUOTES rows per CREATED column (for each SR#)
 15    (select q.*,
 16       row_number() over (partition by q.sr# order by created desc) rn
 17     from s_quotes q
 18    )
 19  -- your 1st query, slightly modified - it joins T_QUOTES and has another join condition
 20  select sr.sr#, sr.sub_status, sq.quotes_status, sr.Equipment_status
 21  from s_sr sr left join t_quotes sq on sq.sr# = sr.sr#
 22                                    and sq.rn = 1;

SR#          SUB_STATUS QUOTES_STATUS   EQUIPMENT_STAT
------------ ---------- --------------- --------------
1-5676068874 In Process Quote-Cancelled System down
1-7576068874            Open            System running
1-8376068836 In Process                 System down

SQL>

CodePudding user response:

The easiest solution is a lateral join (OUTER APPLY) where you can select the latest sq row for a sr row.

select sr.sr#, sr.sub_status, sq.quotes_status, sr.equipment_status
from svcops_emea.s_sr sr
outer apply
(
  select *
  from svcops_emea.s_quotes
  where s_quotes.sr# = sr.sr#
  order by created desc
  fetch first row only
) sq
where sr.srtype = 'repair';

Your own query is close, too. Only, don't join. Use INor EXISTS for the lookup in the ON clause:

Select sr.sr#, sr.sub_status, sq.quotes_status, sr.Equipment_status 
from svcops_emea.s_sr sr 
left join svcops_emea.s_quotes sq
  on sq.sr# = sr.sr# 
  and (sq.sr#, sq.Created) in
  ( 
    Select sr#, max(Created)
    from svcops_emea.s_quotes 
    group by sr#
  )
Where s.srtype = 'Repair';

Anoter solution would be to get the lastest status with Oracle's KEEP LAST aggregation function. And yet another would use a window function, e.g. MAX OVER.

  •  Tags:  
  • Related