2010-06-23 5 views
2

J'ai une table commeComment sélectionner une valeur de colonne correspondant à une ligne renvoyée par une fonction d'agrégat MySQL?

 date    user_id   page_id 
2010-06-19 16:00:00   1    4 
2010-06-19 16:00:00   3    4 
2010-06-20 07:10:00   1    1 
2010-06-20 12:00:10   1    2 
2010-06-20 12:00:10   1    3 
2010-06-20 13:05:00   2    1 
2010-06-20 14:10:00   3    1 
2010-06-21 17:00:00   2    1   

Je veux écrire une requête qui renverra la dernière page_id pour les utilisateurs qui ne sont pas visités au dernier jour.

Alors, je peux trouver qui n'a pas visité dans le dernier jour avec:

SELECT user_id, MAX(page_id) 
FROM page_views GROUP BY user_id 
HAVING MAX(date) < DATE_SUB(NOW(), INTERVAL 1 DAY); 

Cependant, comment puis-je trouver la dernière page_id vu pour ces utilisateurs? c'est-à-dire que je veux savoir quel page_id correspond à la valeur dans la même ligne que MAX (date). Dans le cas où il y a plusieurs pages vues par date, je peux simplement sélectionner MAX (page_id).

La sortie attendue de ci-dessus doit être (si retourne maintenant() 2010-06-21 18:00:00):

user_id  page_id 
    1   3 
    3   1 
  • user_id 1 dernière a visité plus il y a un jour à 2010- 06-20 12:00:10, et le MAX (page_id) était 3.
  • utilisateur_id 2 dernier visité il ya moins d'un jour, de sorte qu'ils sont ignorés.
  • user_id 3 dernière visite plus d'un jour il y a, et leur dernier page_id était 1.

Comment puis-je y parvenir? Je dois utiliser uniquement SQL. J'utilise une dérivée MySQL qui nécessite que toutes les colonnes de la clause SELECT soient déclarées dans la clause GROUP BY (c'est un peu plus conforme aux normes).

Merci.

Répondre

1

Je pouvais voir différentes approches. Par exemple:

select a.user_id, a.page_id 
from page_views a 
inner join (SELECT user_id, MAX(date) as date 
FROM page_views GROUP BY user_id 
HAVING MAX(date) < DATE_SUB(NOW(), INTERVAL 1 DAY)) b on a.user_id = b.user_id 
    and a.date = b.date 

Il pourrait être mis en œuvre plus efficace dans MS SQL ou Oracle avec des fonctions fenêtré.

Une autre idée:

select a.user_id, a.page_id 
from page_views a 
where date < DATE_SUB(NOW(), INTERVAL 1 DAY) 
    and not exist(select 1 from page_views b 
     where a.user_id = b.user_id and b.date > a.date) 
+0

Je ne sais pas est-il possible d'avoir plusieurs page_id pour la même user_id dans le même temps. Si oui, vous pouvez éventuellement ajouter un groupe à cette requête – burnall

+0

C'est super, merci. Je ne savais pas que vous pouviez rejoindre plusieurs colonnes, et j'avais oublié le mot clé EXIST. –

Questions connexes