2010-01-29 2 views
1

J'ai une table qui enregistre les pages vues de chaque utilisateur:SELECT pour choisir les utilisateurs qui ont tous deux affiché une page

+--------------+--------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+--------------+--------------+------+-----+---------+----------------+ 
| view_id  | int(11)  | NO | PRI | NULL | auto_increment | 
| page_id  | int(11)  | YES | MUL | NULL |    | 
| user_id  | int(11)  | YES | MUL | NULL |    | 
+--------------+--------------+------+-----+---------+----------------+ 

Pour chaque paire d'utilisateurs, je voudrais générer un compte de combien de pages ils ont tous deux regardé.

Je ne sais tout simplement pas comment faire. :) J'utilise mysql, au cas où il aurait une fonctionnalité non-standard qui rendrait cela un jeu d'enfant.

+0

Vous voulez faire cela pour chaque paire possible? Cela peut être beaucoup de résultats, (n^2-n)/2 je pense être exact. –

+0

vous voulez toutes les combinaisons d'utilisateurs? Si vous avez 1000 utilisateurs, 1000 choisir 2 = 499 500, 10000 utilisateurs: 10000 choisir 2 = 49 995 000 ...> ___> – Lukman

+0

@Lukman, je ne suis pas sûr de comprendre ce que vous voulez dire. – laramichaels

Répondre

3
select u1.user_id, u2.user_id, count(distinct u1.page_id) as NumPages 
from logtable u1 
    join 
    logtable u2 
    on u1.page_id = u2.page_id 
    and u1.user_id < u2.user_id /* This avoids counting pairs twice */ 
group by u1.user_id, u2.user_id; 

Mais vous devriez envisager cette filtrer un peu ...

(Edité ci-dessus pour mettre u1.page_id, il était à l'origine juste page_id, ce qui est vraiment mauvais de moi)

+0

@Rob, merci! Après quelques tests, cela semble faire exactement ce que je cherchais. Juste une note: mysql se plaignait que page_id soit ambigu, donc j'ai remplacé [count suivant Tor] 'count (distinct page_id)' par 'count (distinct u1.page_id)'. Merci beaucoup. :) – laramichaels

+0

@ Rob, j'ai mal classé et supprimé mon précédent upvote. Pour que je puisse le rajouter, vous devez apporter quelques modifications mineures (ajouter un mot ou plus?) À votre réponse. :) – laramichaels

+0

@Rob, encore merci pour votre réponse. :) J'obtiens un ensemble de résultats qui contient seulement 300k enregistrements. Avec 10k utilisateurs différents, je m'attendais à un résultat beaucoup plus grand tableau [(10k ** 2-10k)/2) ~ 55m enregistrements]. Comme aucune paire n'est signalée avec NumPages = 0, je devine que la requête ne liste que les paires qui partagent au moins une page - est-ce correct? Ou est-ce que je fais quelque chose de mal? – laramichaels

2
SELECT DISTINCT page_id 
FROM logtable 
WHERE user_id = 1 OR user_id = 2 
GROUP BY page_id 
HAVING COUNT(DISTINCT user_id) = 2 

Ce tableau retourne toutes les pages qu'ils ont regardé les deux à. Si vous voulez le nombre, alors faites-en une sous-requête et comptez les lignes.

SELECT COUNT(*) FROM (the query above) s; 

mise à jour, nous allons le faire pour toutes les paires d'utilisateurs alors.

SELECT u1.user_id, u2.user_id, COUNT(DISTINCT u1.page_id) 
FROM logtable u1, logtable u2 
WHERE u1.user_id < u2.user_id 
    AND u1.page_id = u2.page_id 
GROUP BY u1.user_id, u2.user_id 
+0

Êtes-vous sûr de répondre à la question? – Lukman

+0

L'OP veut voir les pages vues par les deux utilisateurs. – danben

+0

@Lukman @danben - Édité et testé maintenant, ça devrait fonctionner. –

0
select a.user_id as user1, b.user_id as user2, count(distinct a.page_id) as views 
from yourtable a, yourtable b 
where a.page_id = b.page_id 
and a.user_id < b.user_id 
group by a.user_id, b.user_id 

changement yourtable au nom de votre table ..

+0

count (*) ne fonctionne pas ici, car les utilisateurs peuvent visiter la même page à plusieurs reprises. S'ils ont visité une page trois fois, cela comptera cette page trop de fois. Si le tableau enregistre uniquement la première visite sur chaque page, alors ce sera parfait. –

+0

@Rob: fixé en utilisant count (distinct a.page_id) – Lukman

0

Fo r users_ids 100 et 200.

SELECT 
    page_id 
FROM table1 
WHERE user_id IN (100, 200) 
GROUP BY page_id 
HAVING MAX(CASE WHEN user_id = 100 THEN 1 ELSE 0 END) = 1 
    AND MAX(CASE WHEN user_id = 200 THEN 1 ELSE 0 END) = 1; 
Questions connexes