2009-06-02 19 views
5
problema

Tengo una consulta que tiene un número de combinaciones y tiene unos criterios en la cláusula WHERE, y estoy terminando con un resultado que en esencia es el siguiente:grupo de SQL por

| userId |  date | otherData | 
|--------+------------+------------| 
|  1 | 2008-01-01 | different | 
|  1 | 2009-01-01 |  info | 
|  1 | 2010-01-01 |  for | 
|  2 | 2008-01-01 |  each | 
|  3 | 2008-01-01 |  row | 
|  3 | 2009-01-01 |  here | 

Así , en esencia para cada usuario, habrá una o más fechas en el pasado, y 0 o más fechas en el futuro.

Necesito de alguna manera reducir el conjunto de datos a una fila por usuario, seleccionando solo la fila que tiene la última fecha pasada. Es decir, con lo que la magia GROUP BY o HAVING cláusula se añade, el resultado anterior quedaría así:

| userId |  date | otherData | 
|--------+------------+------------| 
|  1 | 2009-01-01 |  info | 
|  2 | 2008-01-01 |  each | 
|  3 | 2009-01-01 |  here | 

Respuesta

5

Creo que usted no desea utilizar GROUP BY/TIENE porque usted está interesado en exactamente 1 fila por usuario, y esa fila ya existe en la tabla tal como está. Esto requiere una cláusula WHERE y no GROUP BY/HAVING.

Mi sugerencia es que en la cláusula WHERE, agregue la condición de que la fecha debe ser igual al resultado de una subconsulta. Eso subconsulta debe:

  1. Seleccione el máximo (fecha)
  2. tener una cláusula WHERE que limita la fecha a ser más pequeños que AHORA
  3. Tener una cláusula WHERE con el ID de usuario es igual identificador de usuario de consulta externa

Para evitar casos en los que un determinado usuario puede tener dos entradas con la misma fecha que también es la fecha máxima "aprobada", también debe agregar DISTINCT.

Espero que ayude.

+0

funciona bien !! pero al agregar DISTINCT no elimina valores duplicados, ¿alguna sugerencia? – Rakesh

0

De esta manera:

select a.userId, a.date, b.userId, b.otherData 
from table1 as a 
left outer join table2 as b on a.userId = b.userId 
where b.Id in (
    select top 1 Id from table2 as c where c.userId = a.userId) 
0
 
Select 
    userID, date, otherData 
from 
    yourTable t1 
where 
    date = 
    (select max(date) from yourTable t2 
    where t1.userID=t2.userID) 
0
select T.userid, T.date, T.otherdata 
from 
    T, 
    (select userid, max(date) max_date from T group by userid) GT 
where 
    T.userid = GT.userid and T.date = GT.max_date 

Explicación: interior seleccionar - izolate sólo los registros con la fecha máxima para cada usuario. selección completa - unir registros izolados con la tabla original, para obtener el otro campo de datos.

Supuse que solo hay una fecha máxima para una identificación de usuario. Por favor, diga si es la suposición correcta.