views:

122

answers:

3

Hello,

I am trying to write a query that will return only the most recent results. The table I am pulling information from has no uniqiue columns, and contains information on rate changes so for any particular client there can be several rate changes - I only want the most recent rate change for each client.

The structure is:

mrmatter VARCHAR(14)
mrtk VARCHAR(14)
mreffdate DATETIME
mrtitle VARCHAR(100)
mrrate INT
mrdevper INT

Some sample data is:

mrmatter         mrtk      mreffdate                  mrtitle  mrrate   mrdevper
184-00111        0005      2001-03-19 00:00:00.000    !        250      NULL
184-00111        0259      2001-03-19 00:00:00.000    !        220      NULL
184-00111        9210      2001-03-19 00:00:00.000    !        220      NULL
184-00111        0005      2007-07-01 00:00:00.000    !        NULL     NULL

From the data above you can see there is two mrtk (0005), from these results it should only return three instead of the four rows.

The query isnt just on mrtk, instead of mrtk there could be a mrtitle in which case I would need to find the most recent date, when there is multiples.

I have tried the following query, it returns the results sorted in newest to oldest, but it returns four rows (two 0005) instead of only the three. I have tried different ways of doing the same query but it all returns the same results.

SELECT mrmatter,mrtk,mrrate,MAX(mreffdate) AS 'MostRecent'
FROM mexrate
WHERE mrmatter='184866-00111'
GROUP BY mrmatter,mrtk,mrrate

Any assistance that can be provided would be greatly appreciated.

UPDATE: The mrrate column can contain nulls, and the nulls can be the most recent entry. What I am after is the most recent entry for the same mrmatter AND (mrtk OR mrtitle).

Some more sample data is:

mrmatter      mrtk               mrtk     mrrate   mreffdate
100626-01406    Senior Assoc ! 235.000 2006-01-25 00:00:00.000
100626-01406    Solicitor   ! 235.000 2006-01-25 00:00:00.000
100626-01407    Associate          ! 265.000 2006-01-30 00:00:00.000
100626-01407    Associate          ! 276.000 2007-07-01 00:00:00.000
100626-01407    Partner          ! 265.000 2006-01-30 00:00:00.000
100626-01407    Partner          ! 276.000 2007-07-01 00:00:00.000
100626-01407    Senior Assoc ! 265.000 2006-01-30 00:00:00.000
100626-01407    Senior Assoc ! 276.000 2007-07-01 00:00:00.000

Matt

+1  A: 

The group by clause have mrrate column as well. For the two rows of mrtk(0005), first row have mrrate as 250 and second row have mrrate as NULL. This will certainly result in two rows of 0005.

The query is working fine. You may remove mrrate from group by but probably there is some functionality attached to it which is not clear.

Bhushan
Removing the mrrate column from the group by results in: Column 'mexrate.mrrate' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Lima
A: 

try this:

DECLARE @YourTable table
(mrmatter VARCHAR(14)
,mrtk VARCHAR(14)
,mreffdate DATETIME
,mrtitle VARCHAR(100)
,mrrate INT
,mrdevper INT
)

insert into @YourTable values('184-00111',        '0005'     , '2001-03-19 00:00:00.000'   , '!'    ,    250   ,   NULL)
insert into @YourTable values('184-00111',        '0259'     , '2001-03-19 00:00:00.000'   , '!'    ,    220   ,   NULL)
insert into @YourTable values('184-00111',        '9210'     , '2001-03-19 00:00:00.000'   , '!'    ,    220   ,   NULL)
insert into @YourTable values('184-00111',        '0005'     , '2007-07-01 00:00:00.000'   , '!'    ,    NULL  ,   NULL)

SELECT
    mrmatter
        ,mrtk
        ,mreffdate
        ,mrtitle
        ,mrrate
        ,mrdevper
    FROM (SELECT
              row_number() over(partition by mrtk order by mrtk,mreffdate DESC) AS RankValue,*
              FROM @YourTable
         ) dt
    WHERE RankValue=1

output:

mrmatter       mrtk           mreffdate               mrtitle  mrrate      mrdevper
-------------- -------------- ----------------------- -------- ----------- -----------
184-00111      0005           2007-07-01 00:00:00.000 !        NULL        NULL
184-00111      0259           2001-03-19 00:00:00.000 !        220         NULL
184-00111      9210           2001-03-19 00:00:00.000 !        220         NULL

(3 row(s) affected)

EDIT
I've read your question again, and I'm not 100% sure for your grouping requirement, perhaps because the sample data is a little sparse. This may be the query for you:

SELECT
    mrmatter
        ,mrtk
        ,mreffdate
        ,mrtitle
        ,mrrate
        ,mrdevper
    FROM (SELECT
              row_number() over(partition by mrmatter,mrtk,mrrate order by mrmatter,mrtk,mrrate,mreffdate DESC) AS RankValue,*
              FROM @YourTable
         ) dt
    WHERE RankValue=1

It will yield the same 4 rows as your query, because you are trying to put mrrate into the group, and 0005 has two: 250 and NULL. If you want to eliminate NULL use:

SELECT
    mrmatter
        ,mrtk
        ,mreffdate
        ,mrtitle
        ,mrrate
        ,mrdevper
    FROM (SELECT
              row_number() over(partition by mrmatter,mrtk,mrrate order by mrmatter,mrtk,mrrate,mreffdate DESC) AS RankValue,*
              FROM @YourTable
              WHERE mrrate IS NOT NULL
         ) dt
    WHERE RankValue=1
KM
Firstly, row_number is for SQL 2000, so neither of these will work. I also dont want to exclude the NULL results as if the NULL results are the most recent result for mrmatter AND (mrtitle OR mrtk) then I want it to display.Thanks,Matt
Lima
KM
A: 

I was able to achieve what I was after by using this query:

SELECT t1.mrmatter,t2.mrtk,t1.mrrate,t2.MostRecent
FROM mexrate t1
INNER JOIN
(
    SELECT DISTINCT(mrtk),MAX(mreffdate) AS MostRecent
    FROM mexrate
    WHERE mrmatter='184866-00111'    
    GROUP BY mrtk
) t2 ON t1.mrtk=t2.mrtk AND t1.mreffdate=t2.MostRecent
WHERE mrmatter='184866-00111' 

Thanks everyone for your assistance with this problem, it is, as always, greatly appreciated.

Matt

Lima