114

Using the following query and results, I'm looking for the most recent entry where the ChargeId and ChargeType are unique.

select chargeId, chargeType, serviceMonth from invoice

    CHARGEID    CHARGETYPE  SERVICEMONTH
1   101         R           8/1/2008
2   161         N           2/1/2008
3   101         R           2/1/2008
4   101         R           3/1/2008
5   101         R           4/1/2008
6   101         R           5/1/2008
7   101         R           6/1/2008
8   101         R           7/1/2008

Desired:

    CHARGEID    CHARGETYPE  SERVICEMONTH
1   101         R           8/1/2008
2   161         N           2/1/2008
RasmusN
  • 147
  • 1
  • 12
jgreep
  • 2,111
  • 4
  • 23
  • 31

6 Answers6

160

You can use a GROUP BY to group items by type and id. Then you can use the MAX() Aggregate function to get the most recent service month. The below returns a result set with ChargeId, ChargeType, and MostRecentServiceMonth

SELECT
  CHARGEID,
  CHARGETYPE,
  MAX(SERVICEMONTH) AS "MostRecentServiceMonth"
FROM INVOICE
GROUP BY CHARGEID, CHARGETYPE
Adam Pierce
  • 33,531
  • 22
  • 69
  • 89
Mitchel Sellers
  • 62,228
  • 14
  • 110
  • 173
64

So this isn't what the requester was asking for but it is the answer to "SQL selecting rows by most recent date".

Modified from http://wiki.lessthandot.com/index.php/Returning_The_Maximum_Value_For_A_Row

SELECT t.chargeId, t.chargeType, t.serviceMonth FROM( 
    SELECT chargeId,MAX(serviceMonth) AS serviceMonth
    FROM invoice
    GROUP BY chargeId) x 
    JOIN invoice t ON x.chargeId =t.chargeId
    AND x.serviceMonth = t.serviceMonth
Community
  • 1
  • 1
tvanfosson
  • 524,688
  • 99
  • 697
  • 795
11
SELECT chargeId, chargeType, MAX(serviceMonth) AS serviceMonth 
FROM invoice
GROUP BY chargeId, chargeType
Ben Hoffstein
  • 102,129
  • 8
  • 104
  • 120
11

I see most of the developers use inline query without looking out it's impact on huge data.

in simple you can achieve this by:

select a.chargeId, a.chargeType, a.serviceMonth 
from invoice a
left outer join invoice b
on a.chargeId=b.chargeId and a.serviceMonth <b.serviceMonth 
where b.chargeId is null
order by a.serviceMonth desc
sujeet
  • 587
  • 5
  • 8
1
select to.chargeid,t0.po,i.chargetype from invoice i
inner join
(select chargeid,max(servicemonth)po from invoice 
group by chargeid)t0
on i.chargeid=t0.chargeid

The above query will work if the distinct charge id has different chargetype combinations.Hope this simple query helps with little performance time into consideration...

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
0

Demo at sqlfiddle:

  1. Classical way.
select 
    chargeid, 
    chargetype,
    SERVICEMONTH
from invoice t0
where t0.SERVICEMONTH = (
    select max(SERVICEMONTH) 
    from invoice t1 
    where t1.chargeid = t0.chargeid
    and t1.chargetype = t0.chargetype
);
  1. Using window functions.
with w_o as (
    select
        chargeid, 
        chargetype,
        SERVICEMONTH,
        row_number() OVER (PARTITION BY chargeid, chargetype ORDER BY SERVICEMONTH DESC) rn
    from invoice
)
select
    chargeid, 
    chargetype,
    SERVICEMONTH
from w_o
where rn = 1;

It is nice to understand and be able to use both styles.

Shmiel
  • 1,201
  • 10
  • 25
Bozon
  • 46
  • 3