2009-11-25 7 views
32

Quand je lance l'instruction SQL suivante:SQL pas un seul groupe fonction de groupe

SELECT MAX(SUM(TIME)) 
FROM downloads 
GROUP BY SSN 

Il renvoie la valeur de la somme maximale de téléchargements par un client, si je tente de trouver le numéro de sécurité sociale qui valeur max appartient en l'ajoutant à l'instruction select:

SELECT SSN, MAX(SUM(TIME)) 
FROM downloads 
GROUP BY SSN 

je reçois l'erreur suivante:

not a single-group group function

Je ne comprends pas pourquoi il lance cette erreur. Une recherche sur Google est venu avec l'action suivante:

chute soit la fonction de groupe ou l'expression individuelle de colonne de la liste SELECT ou ajouter une clause GROUP BY qui comprend toutes les expressions de colonne individuelles figurant

D'après ce que je pense que ce dit - l'abandon de la fonction de groupe rend la valeur de la somme invalide - l'abandon de l'expression de colonne individuelle (SSN) me donnera juste la somme maximale - je ne suis pas sûr de cette troisième partie.

Quelqu'un pourrait-il guider dans la bonne direction?

-Tomek

EDIT: TIME dans cette base de données fait référence au nombre de fois téléchargé

Répondre

34

Eh bien, le problème est simplement mis que la somme (TIME) pour un SSN spécifique sur votre requête est un valeur, donc il s'oppose à MAX car cela n'a pas de sens (le maximum d'une seule valeur est sans signification).

Je ne sais pas quel serveur de base de données SQL que vous utilisez, mais je suppose que vous voulez une requête plus comme ceci (écrit avec un arrière-plan MSSQL - peuvent avoir besoin d'Translating au serveur SQL que vous utilisez):

SELECT TOP 1 SSN, SUM(TIME) 
FROM downloads 
GROUP BY SSN 
ORDER BY 2 DESC 

Cela vous donnera le SSN avec le temps total le plus élevé et le temps total pour cela.

Edition - Si vous avez plusieurs avec un temps égal et voulez tout ce que vous utilisez:

SELECT 
SSN, SUM(TIME) 
FROM downloads 
GROUP BY SSN 
HAVING SUM(TIME)=(SELECT MAX(SUM(TIME)) FROM downloads GROUP BY SSN)) 
+0

J'utilise oracle et je ne suis pas familier avec l'acquisition de lignes spécifiques.Cependant, que se passe-t-il s'il y a des clients qui sont liés pour avoir le maximum de téléchargements? – Tomek

+0

S'il y avait un multiple avec le même montant, il serait essentiellement aléatoire et vous l'obtiendrez (il y a probablement un ordre à un niveau bas mais je ne le saurais pas et je ne m'en fierais pas). Vous pouvez ajouter des clauses supplémentaires à la commande si vous souhaitez spécifier comment la commander vous-même. Si vous voulez obtenir tous ceux liés pour le premier je crois que vous aurez besoin de requêtes imbriquées, une pour obtenir le temps maximum puis une autre pour retirer tous ceux qui le rencontrent (quelque chose comme "SELECT SSN, SUM (TIME) FROM téléchargements GROUP BY SSN AYANT SUM (TIME) = (SÉLECT MAX (SUM (TIME)) FROM téléchargements GROUP BY SSN)) ") – fyjham

+0

PS: Pas sûr à 100% si HAVING existe dans Oracle - quelqu'un d'autre peut être en mesure de clarifier cela. La plupart de mon expérience est TSQL. – fyjham

10

Si vous voulez nombre de téléchargements pour chaque client, utilisez:

select ssn 
    , sum(time) 
    from downloads 
group by ssn 

Si vous voulez un seul enregistrement - pour un client avec le plus grand nombre de téléchargements - utiliser:

select * 
    from (
     select ssn 
      , sum(time) 
      from downloads 
     group by ssn 
     order by sum(time) desc 
     ) 
where rownum = 1 

Cependant si vous êtes nt pour voir tous les clients avec le même nombre de téléchargements, qui partagent la position la plus haute, utilisez:

select * 
    from (
     select ssn 
      , sum(time) 
      , dense_rank() over (order by sum(time) desc) r 
      from downloads 
     group by ssn 
     ) 
where r = 1 
+0

Votre deuxième exemple lui donnerait le client avec le plus petit nombre à moins que votre commande en descendant – Khb

+0

Khb, vous avez raison. Je l'ai corrigé. –

2

Peut-être que vous trouverez ce simple

select * from (
    select ssn, sum(time) from downloads 
    group by ssn 
    order by sum(time) desc 
) where rownum <= 10 --top 10 downloaders 

Cordialement
K