Search code examples
sqloracle-sqldeveloper

Is there a SQL query/function that returns a grouping of rows when only one row meets requirements of the WHERE clause?


I have a database table (INVOICES) that records approval of invoices:

    ORDER | INVOICE_NBR | APPROVAL_LEVEL | APPROVAL_DATE | APPROVER  
    123   |001          |1               |02-FEB-20      |John Smith
    123   |001          |2               |17-FEB-20      |Jane Smith
    123   |001          |3               |25-FEB-20      |Matt Jones
    123   |002          |1               |10-MAR-20      |John Smith
    123   |002          |2               |21-MAR-20      |Jane Smith
    123   |002          |3               |02-APR-20      |Matt Jones

If any approval of an invoice was made after a certain date, I want to retrieve all approvals for that invoice. I have attempted to group each invoice and then use a HAVING clause...

Select ORDER, INVOICE_NBR, APPROVAL_LEVEL, APPROVER, APPROVAL_DATE
From INVOICES
Group By ORDER, INVOICE_NBR, APPROVAL_LEVEL, APPROVER, APPROVAL_DATE
Having APPROVAL_DATE >= '01-APR-20'

...but I still only return the last row of the table above. How do I return all of the approval levels for invoice 002 based on any of its approval dates falling after 01-APR-20?


Solution

  • Use exists:

    select i.*
    from invoices i
    where exists (select 1
                  from invoices i2
                  where i2.invoice_nbr = i.invoice_nbr and
                        i2.approval_date >= date '2020-04-01'
                 );
    

    You can also use a window functions:

    select i.*
    from (select i.*,
                 max(approval_date) over (partition by invoice_nbr) as max_approval_date
          from invoices i
         ) i
    where max_approval_date >= date '2020-04-01';