2017-04-26 3 views
1

Question! J'essaie d'énumérer tous les livres et leur sujet de livre correspondant, le coût moyen et le coût régulier.Sous-requête corrélée pour trouver AVG de certains groupes

Jusqu'à présent, ma question est ...

SELECT BOOK_SUBJECT, AVG(BOOK_COST) 
FROM BOOK 
GROUP BY BOOK_SUBJECT 

Cette requête me donne la moyenne des quatre groupes coût total. Final out put should look like this Je dois apporter BOOK_NUM, BOOK_TITLE, BOOK_SUBJECT, BOOK_COST, mais je suis incapable de comprendre. Quelqu'un peut-il aider? Sous-requête corrélée?

+0

Vous utilisez SQL-Server, MySQL, ou autre chose? S'il vous plaît ajouter une étiquette pour ce que vous utilisez, mais pas les autres. – toonice

+0

Vous devez également inclure la structure complète de la table du livre (et de toutes les autres tables auxquelles elle se joint). Sinon, les réponses seront de la pure spéculation – StevieG

Répondre

0

S'il vous plaît essayez ce qui suit ...

SELECT BOOK_NUM AS Number, 
     BOOK_TITLE AS Title, 
     BOOK.BOOK_SUBJECT AS Subject, 
     BOOK_COST AS Cost, 
     AVG_BOOK_COST AS 'Avg Cost' 
FROM BOOK 
JOIN (SELECT BOOK_SUBJECT AS BOOK_SUBJECT, 
       AVG(BOOK_COST) AS AVG_BOOK_COST 
     FROM BOOK 
     GROUP BY BOOK_SUBJECT 
    ) AS SUBJECT_AVG_FINDER ON BOOK.BOOK_SUBJECT = SUBJECT_AVG_FINDER.BOOK_SUBJECT 
ORDER BY BOOK_NUM; 

Pour calculer la moyenne pour chaque sujet, nous devons regrouper les contenus de BOOK par BOOK_SUBJECT et utilisez AVG(BOOK_COST) pour trouver la moyenne pour chaque groupe. Mais nous souhaitons également éviter de regrouper les autres champs dans BOOK, en ayant à la place les champs spécifiés de chaque enregistrement dans Book affiché avec leur coût moyen BOOK_SUBJECT à la fin. Cela suggère qu'un INNER JOIN entre BOOK et une sous-requête qui est utilisée pour trouver la moyenne des coûts moyens pour chaque sujet.

J'utilise le code suivant pour trouver le coût moyen moyen pour chacun des thèmes énumérés dans BOOK ...

SELECT BOOK_SUBJECT AS BOOK_SUBJECT, 
     AVG(BOOK_COST) AS AVG_BOOK_COST 
FROM BOOK 
GROUP BY BOOK_SUBJECT 

Nous devons sélectionner BOOK_SUBJECT en partie parce que la clause GROUP BY exige et en partie parce que nous en aurons besoin pour joindre la table générée par cette sous-requête à la liste non groupée de BOOK.

En donnant AVG(BOOK_COST), l'alias de AVG_BOOK_COST facilite beaucoup la référence à ce champ généré.

En l'absence d'un type de jointure avant le mot JOIN la plupart des versions de SQL assumeront une INNER JOIN, bien que tous permettent INNER JOIN à utiliser et certains vous obliger à le faire. Par défaut, moi et beaucoup d'autres utilisent simplement JOIN.

Une fois la jonction est effectuée chaque enregistrement à partir de BOOK aura une copie du disque correspondant de notre sous-requête (que j'ai donné un alias de SUBJECT_AVG_FINDER), laissant chaque enregistrement avec deux champs appelés BOOK_SUBJECT. Afin de ne pas confondre votre version de SQL, nous devons spécifier la table/sous-requête avec le nom du champ où une telle duplication se produit, donc BOOK.BOOK_SUBJECT dans la troisième ligne de l'instruction globale.

Chaque champ a reçu un alias selon l'image de sortie finale souhaitée.

Je suppose qu'il n'est pas nécessaire de répliquer le champ de numéro de ligne. Si cela est incorrect, veuillez indiquer le contraire.

Enfin, j'ai trié les résultats selon votre sortie désirée en ajoutant la ligne ORDER BY BOOK_NUM.

À titre de conseil, bien que cela soit autorisé, évitez d'utiliser des cris (c.-à-d.en majuscule) vos noms de champs, noms de tables et alias '(sauf si vous êtes obligé de le faire), mais criez quand même les choses SQL (comme SELECT, FROM, AS, etc.). Cela peut rendre une déclaration plus facile à lire et à déboguer en fournissant un indice visuel de la façon dont vous essayez d'utiliser chaque mot. Je suggère la manière suivante de présenter notre instruction SQL à la place ...

SELECT book_num AS Number, 
     book_title AS Title, 
     book.book_subject AS Subject, 
     book_cost AS Cost, 
     avg_book_cost AS 'Avg Cost' 
FROM book 
JOIN (SELECT book_subject AS book_subject, 
       AVG(book_cost) AS avg_book_cost 
     FROM book 
     GROUP BY book_subject 
    ) AS subject_avg_finder ON book.book_subject = subject_avg_finder.book_subject 
ORDER BY book_num; 

Si vous avez des questions ou des commentaires, alors s'il vous plaît ne hésitez pas à poster un commentaire en conséquence.

0

Utilisez un sous-requête pour le faire:

SELECT BOOK.BOOK_NUM, BOOK.BOOK_TITLE, BOOK.BOOK_SUBJECT, BOOK.BOOK_COST, T.AVG_COST 
FROM BOOK 
INNER JOIN (
    SELECT BOOK_SUBJECT, AVG(BOOK_COST) AVG_COST 
    FROM BOOK 
    GROUP BY BOOK_SUBJECT 
) T ON BOOK.BOOK_SUBJECT = T.BOOK_SUBJECT 
0

Utilisez ce code

SELECT BOOK_NUM, BOOK_TITLE, BOOK_SUBJECT, BOOK_COST, 
AVG(BOOK_COST) OVER(PARTITION BY BOOK_SUBJECT) AS AVG_COST 
FROM BOOK