Question! J'essaie de lister tous les livres et leur sujet de livre correspondant, leur coût moyen et leur coût régulier.

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 du coût total des quatre groupes. La sortie finale devrait ressembler à ceci Je dois apporter BOOK_NUM, BOOK_TITLE, BOOK_SUBJECT, BOOK_COST, mais je n'arrive pas à comprendre. Quelqu'un peut-il aider? Sous-requête corrélée?

1
laxurent 26 avril 2017 à 05:00

3 réponses

Meilleure réponse

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 le contenu de BOOK par BOOK_SUBJECT et utiliser AVG( BOOK_COST ) pour trouver la moyenne moyenne pour chaque groupe. Mais nous souhaitons également éviter de regrouper les autres champs dans BOOK, au lieu d'avoir les champs spécifiés de chaque enregistrement dans Book affichés avec leur coût moyen de BOOK_SUBJECT cloué à la fin. Cela suggère qu'un INNER JOIN entre BOOK et une sous-requête qui est utilisé pour trouver la moyenne moyenne du coût pour chaque sujet.

J'ai utilisé le code suivant pour trouver le coût moyen moyen pour chaque sujet répertorié 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 l'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.

Donner à AVG( BOOK_COST ) l'alias de AVG_BOOK_COST rend la référence à ce champ généré beaucoup plus facile.

En l'absence d'un type de jointure avant le mot JOIN, la plupart des versions de SQL supposeront un INNER JOIN, bien que toutes autorisent l'utilisation de INNER JOIN et que certaines vous obligent à le faire. Par défaut, moi et beaucoup d'autres utilisent simplement JOIN.

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

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

J'ai supposé qu'il n'était pas nécessaire de reproduire 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 souhaitée en ajoutant la ligne ORDER BY BOOK_NUM.

Comme astuce, bien que cela soit autorisé, vous devriez éviter d'utiliser des cris (c'est-à-dire des majuscules) vos noms de champs, noms de tables et alias (sauf si vous êtes obligé de le faire), mais toujours crier les trucs SQL (comme {{X0}) }, FROM, AS, etc.). Cela peut faciliter la lecture et le débogage d'une instruction en fournissant un indice visuel sur la manière dont vous essayez d'utiliser chaque mot. Je suggère plutôt la manière suivante de présenter notre instruction SQL ...

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, n'hésitez pas à publier un commentaire en conséquence.

0
toonice 27 avril 2017 à 00:00

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
0
pallavimane 11 oct. 2017 à 01:18

Utilisez une sous-requête pour ce 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
Blank 26 avril 2017 à 02:36