6

I have this table:

Department   NAME   EMAIL         ID     DATE1         DATE2
1            John   [email protected]   74     05/04/2007    05/04/2007
1            Sam    [email protected]   23     05/04/2007    05/04/2007
1            Tom    [email protected]   46     05/04/2007    03/04/2007
1            Bob    [email protected]   23     01/01/2006
2            Tom    [email protected]   62     02/02/2000    05/05/1997

I want to get the row (only one per department) with max DATE1, but it's not unique! So if there is multiple results I want to get the max DATE2, and if there are multiple ones then the one with the biggest ID is returned.

So there result of the query would be:

1            John   [email protected]   74     05/04/2007    05/04/2007
2            Tom    [email protected]   62     02/02/2000    05/05/1997

Thank you very much.

4 Answers 4

18

You need to use the ROW_NUMBER function:

SELECT Department, NAME, EMAIL, ID, DATE1, DATE2
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY Department ORDER BY DATE1 DESC, DATE2 DESC, ID DESC) AS RowNumber, 
       Department, NAME, EMAIL, ID, DATE1, DATE2
FROM MyTable ) t
WHERE RowNumber = 1
Sign up to request clarification or add additional context in comments.

6 Comments

it sound great! does it work for a partition by multiple columns? because my table is much more complicated
@user337746 - Yes, partition by works exactly as a group by statement does.
yes, partition by is similar to group by clause but for the Row_Number function
@user337746 Glad I can help, please don't forget to mark the correct answer for future reference
@BassamMehanni i tried it on oracle, there shouldn't be comma next to Department just space before Order BY and thanks for the solution.
|
5

Use the over clause:

select
    *
from
    (
    select
        Department,
        Name,
        Email,
        ID,
        DATE1,
        DATE2,
        max(DATE1) over (partition by Department) as MaxDate1,
        max(DATE2) over (partition by Department, DATE1) as MaxDate2,
        max(ID) over (partition by Department, DATE1, DATE2) as MaxID
    from
        employees
    ) x
where
    x.DATE1 = x.MaxDate1
    and x.DATE2 = x.MaxDate2
    and x.ID = x.MaxID

2 Comments

Nice, and pretty novel. But wouldn't just using row_number would have less overhead?
@Dems - Absolutely it would. Wanted to give another way to do it if this was just an example and he needed more granular control.
0

Something like....

SELECT y2.*
FROM
(SELECT dept, 
  MAX(
    TO_CHAR(date1,'YYYYHH24MISS') || TO_CHAR(date2,'YYYYHH24MISS') 
    || id) as lastrec
 FROM yourtable y1
 GROUP BY dept) as ilv,
 yourtable y2
 WHERE y2.id=TO_NUMBER(SUBSTR(y2.lastrec, 21))

1 Comment

Ohhh, I get it. But it does assume that the ID field is unique, which hasn't been state. Nice latteral thinking though.
0
SELECT
*
FROM
(
SELECT
    Department,
    Name,
    Email,
    ID,
    DATE1,
    DATE2,
    max(DATE1) over (partition by Department) as MaxDate1,
    max(DATE2) over (partition by Department, DATE1) as MaxDate2,
    max(ID) over (partition by Department, DATE1, DATE2) as MaxID
FROM
    employees
) 
WHERE
x.DATE1 = x.MaxDate1
AND x.DATE2 = x.MaxDate2
AND x.ID = x.MaxID

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.