2011-01-28 16 views
13

Tengo una tabla que contiene (digamos) todas las veces que un usuario miró una página web específica. Los usuarios pueden, por supuesto, miran una página más de una vez, por lo que no puede haber varias entradas para los usuarios y las páginas, así:Cómo seleccionar filas de MySQL según el valor máximo de una columna + agrupación

nid  time user page_id 
25  8000  4  467 
24  7000  1  482 
23  6000  1  484 
22  5000  1  482 
21  4000  5  467 
20  3000  4  467 

Quiero hacer una consulta que devuelve las filas correspondientes a cada página vista por cada usuario WITH THE CATCH QUE si un usuario mira una página más de una vez, obtengo la fila correspondiente a la vista más reciente (es decir, el valor más grande de TIME). Por lo tanto, debería conseguir esto:

nid  time user page_id 
25  8000  4  467 
24  7000  1  482 
23  6000  1  484 
21  4000  5  467 

Perdemos fila 22 porque el usuario 1 miraba la página 482 en un momento posterior, y perdemos fila 20 porque el usuario 4 miró la página 467 en un momento posterior.

Casi tengo esto resuelto, pero no puedo descifrarlo, y al mismo tiempo me convenzo de que los resultados que obtenga serán generalmente correctos y no solo un accidente en mis casos de prueba. Sigo yendo y viniendo entre las consultas GROUP BY o DISTINCT y las consultas integradas, y luego mi cerebro explota. ¿Alguna sugerencia? ¡Gracias!

+0

pregunta Duplicar [http: // stackoverflow.com/questions/612231/how-can-i-select-rows-with-maxcolumn-value-distinct-by-another-column-in-sql] – user1486030

Respuesta

19

Si necesita la fila completa, puede utilizar esto:

SELECT fullTable.nid as nid, 
     recent.time as time, 
     fullTable.user as user, 
     fullTable.page_id as page_id 
    FROM TableName fullTable 
     INNER JOIN (SELECT MAX(t1.time) as time, t1.user, t1.page_id 
         FROM TableName t1 
        GROUP BY user, page_id) recent 
       ON recent.time = fullTable.time AND 
        recent.user = fullTable.user AND 
        recent.page_id = fullTable.page_id 
ORDER BY time DESC 

Si solicita una columna fuera del "grupo por" cláusula, mysql puede devolver cualquier valor para esta columna dentro de este grupo. Entonces, si todos los valores dentro del grupo no son los mismos, ese es su caso, no puede incluirlo directamente en la cláusula de selección, necesita usar un join.

Puede leer más acerca de no agrupados en columnas de MySQL en the reference

Si usted no necesita el campo nid, puede usar este otro:

SELECT MAX(time) as time, user, page_id 
    FROM TableName 
GROUP BY user, page_id 
ORDER BY time DESC 
+0

Sí, esto es lo correcto. ¡Muchas gracias! Probablemente debería haber mencionado que necesito el campo NID; Había llegado a su segundo ejemplo, sin NID, pero eso, como se señaló, no es suficiente. Marcar su respuesta y confirmarla como LA respuesta seguirá; También me doy cinco puntos por reconocer correctamente que nunca hubiera solucionado esto por mi cuenta ... –

1

Prueba esto:

SELECT * 
    FROM <YOUR_TABLE> 
WHERE (user, page_id, time) IN 
    (
    SELECT user, page_id, MAX(time) time 
     FROM <YOUR_TABLE> 
    GROUP BY user, page_id 
    ) 
0
SELECT nid, MAX(time), user, page_id 
FROM TableName 
GROUP BY nid, user, page_id 
Cuestiones relacionadas