4

I have a table that looks like this:

+---------------------------------------------+
| EVENT_ID | ITEM_ID | PERSON_ID | EVENT_DATE |
+---------------------------------------------+
| 123      | 1       | 2         | 21-AUG-03  |
| 124      | 1       | 3         | 22-AUG-03  |
| 125      | 1       | 45        | 23-AUG-03  |
| 126      | 1       | (null)    | 24-AUG-03  |
| 127      | 2       | 2         | 25-AUG-03  |
| 128      | 2       | 6         | 26-AUG-03  |
| 129      | 2       | 1         | 27-AUG-03  |
+---------------------------------------------+

So, I need to get the latest (MAX(event_date)), non-null person_id per item_id. We have come up with a fairly simple PL/SQL approach to this, but were trying to get the job done with straight SQL. Anyone have an idea?

Just as a side-note, the event_id will not always be sequential like this. We have two redundant DB servers.

Thanks ahead of time.

2 Answers 2

6

Try this

create table event_table (
    event_id int,
    item_id int,
    person_id int,
    event_date date
);

insert into event_table values (123, 1, 2,    to_date('21-aug-03','DD-MON-YY'));
insert into event_table values (124, 1, 3,    to_date('22-aug-03','DD-MON-YY')); 
insert into event_table values (125, 1, 45,   to_date('23-aug-03','DD-MON-YY'));  
insert into event_table values (126, 1, null, to_date('24-aug-03','DD-MON-YY'));  
insert into event_table values (127, 2, 2,    to_date('25-aug-03','DD-MON-YY'));  
insert into event_table values (128, 2, 6,    to_date('26-aug-03','DD-MON-YY'));  
insert into event_table values (129, 2, 1,    to_date('27-aug-03','DD-MON-YY'));  


select * from event_table;

select t1.item_id, t1.Person_id, t1.event_date
from event_table t1
join 
(select item_id , max(event_date) max_event_date 
   from event_table where Person_id is not null group by item_id ) t2 
on t1.item_id = t2.item_id and t1.event_date = t2.max_event_date;
3
  • Thank you for the setup ddl/dml. I modified it to be valid Oracle syntax and changed my answer to use your table name. Commented Apr 25, 2011 at 13:02
  • OK. Nalroff tagged it Oracle.
    – bernd_k
    Commented Apr 25, 2011 at 13:28
  • This seems to give me what I'm wanting, so thank you. I will mark it correct if it indeed does after some more testing. Thanks.
    – Andy
    Commented Apr 25, 2011 at 16:17
7

The following requires only one full table scan.

SELECT Item_ID, Person_ID, Event_Date FROM
(
   SELECT Event_ID, Person_ID, Item_ID, Event_Date
      , MAX(EVENT_DATE) OVER (PARTITION BY Item_ID) HighEventDate 
   FROM Event_Table WHERE Person_ID IS NOT NULL
)
WHERE Event_Date = HighEventDate;
2
  • And at first I was tempted to propose to migrate the question to SO
    – bernd_k
    Commented Apr 25, 2011 at 12:28
  • wasn't really sure whether to put it here or SO myself ;)
    – Andy
    Commented Apr 25, 2011 at 16:17

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.