Вопрос

create table client (
  client_id int, 
  name varchar(20)
);

insert into client values (1, 'Google');
insert into client values (2, 'Facebook');

create table client_log (
  client_id int, 
  dt date,
  status varchar(20)
);

insert into client_log values (1, '2014-01-01', 'Pending');
insert into client_log values (1, '2014-01-02', 'Approved');
insert into client_log values (2, '2014-01-03', 'Pending');
insert into client_log values (2, '2014-01-04', 'Declined');

I am trying to get the most recent status for each client. I am expecting a result set of:

| Google   | Approved
| Facebook | Declined

I have reviewed the other SO questions like this, but they mostly use sub queries, and since my data is going to get very large I need to write this efficiently, which I think means using a join.

select c.name, cl.status
from client c
join client_log cl on cl.client_id = c.client_id
join client_log cl2 on cl2.client_id = cl.client_id
group by c.client_id 
having cl.dt = max(cl2.dt)

Error: Unknown column 'cl.dt' in 'having clause'

Это было полезно?

Решение 2

If you want the row with the most recent date:

select cl.*
from client_log cl
where not exists (select 1
                  from client_log cl2
                  where cl2.client_id = cl.client_id and cl2.dt > cl.dt
                 );

To facilitate performance, create an index on client_log(client_id, dt).

Другие советы

Simple ask it to select the row with date value equal to the latest (maximum) date in the table for each client.

Select * From client_log cl
Where dt =
   (Select Max(dt) from client_log 
    Where client_id = cl.client_id)
select c.name, cl.status 
from client c 
join client_log cl 
    on c.client_id = cl.client_id 
where cl.dt = ( select max(dt) 
                from client_log x 
                where x.client_id = cl.client_id );

Here is another way using self join for client_log

select c.*,l.status
from client c
join client_log l on(c.client_id = l.client_id)
join (select client_id ,max(dt) dt 
      from client_log 
      group by client_id) cl
on(l.client_id=cl.client_id and l.dt=cl.dt)

Demo

select c.*,l.status
from client c
join client_log l on(c.client_id = l.client_id)
join  client_log  cl
on(l.client_id=cl.client_id and l.dt > cl.dt)

Demo

select c1.client_id, c1.name, cl1.status from (
  select c.client_id, c.name, Max(cl.dt) as maxdate
  from client c
  join client_log cl on cl.client_id = c.client_id
  group by c.client_id, c.name) C1, 
client_log cl1 
where cl1.client_id = c1.client_id and cl1.dt = C1.maxdate
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top