2010-04-08 9 views
2

J'ai 3 tables:nombre max avec joint

utilisateurs:

Id Login 
1 John 
2 Bill 
3 Jim 

ordinateurs:

Id Name 
1 Computer1 
2 Computer2 
3 Computer3 
4 Computer4 
5 Computer5 

séances:

UserId ComputerId Minutes 
1  2   47 
2  1   32 
1  4   15 
2  5   5 
1  2   7 
1  1   40 
2  5   31 

Je voudrais afficher ce tableau résultant:

Login Total_sess Total_min Most_freq_computer Sess_on_most_freq Min_on_most_freq 
John 4   109   Computer2   2     54 
Bill 3   68   Computer5   2     36 
Jim  -   -   -     -     - 

Moi-même, je ne peux couvrir 3 premières colonnes avec:

SELECT Login, COUNT(sessions.UserId), SUM(Minutes) FROM users 
LEFT JOIN sessions 
ON users.Id = sessions.UserId GROUP BY users.Id 

Et une sorte d'autres colonnes avec:

SELECT main.* 
FROM (SELECT UserId, ComputerId, COUNT(*) AS cnt ,SUM(Minutes) 
FROM sessions 
GROUP BY UserId, ComputerId) AS main 
INNER JOIN (
SELECT ComputerId, MAX(cnt) AS maxCnt FROM (
SELECT ComputerId, UserId, COUNT(*) AS cnt FROM sessions GROUP BY ComputerId, UserId 
) 
AS Counts GROUP BY ComputerId) 
        AS maxes 
ON main.ComputerId = maxes.ComputerId 
AND main.cnt = maxes.maxCnt 

Mais j'ai besoin d'obtenir toute la table résultante dans une requête. Je sens que je fais quelque chose de complètement faux. Besoin d'aide pour.

+1

Il ressemble à une requête - voulez-vous dire que vous ne voulez pas utiliser les requêtes imbriquées En outre, SQL qui utilisez-vous? ? PostreSQL? MySQL? MS SQL? –

Répondre

3

vous êtes ici:

SELECT u.login, t1.total_sess, t1.total_min, t2.mf, t2.sess_mf, t2.min_mf 
FROM  users u 
LEFT JOIN (
    SELECT userid, COUNT(minutes) AS total_sess, SUM(minutes) AS total_min 
    FROM  sessions 
    GROUP BY userid 
) AS t1 ON t1.userid = u.id 
LEFT JOIN (
    SELECT userid, name AS mf, COUNT(*) AS sess_mf, SUM(minutes) AS min_mf 
    FROM  sessions s 
    JOIN  computers c ON c.id = s.computerid 
    GROUP BY userid, computerid 
    HAVING COUNT(computerid) >= ALL(SELECT COUNT(*) 
            FROM  sessions s2 
            WHERE s2.userid = s.userid 
            GROUP BY s2.computerid) 
) AS t2 ON t2.userid = u.id 

J'utilise la syntaxe MySQL, mais il devrait être assez portable.

Si vous avez besoin de quelque chose de plus, n'hésitez pas à demander!

EDIT: Je mis à jour la requête, la précédente était mal :(

+2

@Yassin: Il y a toujours un problème avec votre clause 'HAVING' En ce moment cela fonctionne parce que les deux utilisateurs ont un' Sess_on_most_freq' de 2, mais si vous ajoutez une autre session pour Bill sur ordinateur 5 Ajout de 'WHERE user_id = s.user_id' dans la clause HAVING devrait le corriger –

+0

Merci, vous êtes génial! J'apprécierais que vous me recommandiez quelques livres de goob sur SQL – user311719

+0

+1 pour l'approche – Unreason