J'ai deux tableaux:
COLLEGE MIN(AVG_GPA) ----------------------- INF 3.436
Je dois montrer au collège le GPA moyen le plus bas.
J'ai pu trouver cette requête: p>
MIN(AVG_GPA) ------------ 3.436
Ce qui donne la sortie:
SELECT MIN(avg_gpa) FROM ( SELECT d.college, AVG(s.gpa) FROM huffman_departments d, huffman_students s WHERE s.majorcode = d.deptcode GROUP BY d.college );
J'ai besoin d'une sortie qui ressemble à:
huffman_students ( id (PK), fname, lname, status ("freshman", "sophomore", "junior", "senior"), majorcode (FK - huffman_departments.deptcode), gpa, admittedDate) huffman_departments ( deptcode (PK), deptname, college)
4 Réponses :
Vous pouvez déplacer la requête existante vers une sous-requête (ou un CTE), puis utiliser la fonction analytique ROW_NUMBER pour filtrer l'enregistrement pertinent:
WITH cte AS ( SELECT d.college, AVG(s.gpa) avg_spa FROM huffman_departments d INNER JOIN huffman_students s ON s.majorcode = d.deptcode GROUP BY d.college ) SELECT * FROM ( SELECT c.*, ROW_NUMBER() OVER(ORDER BY avg_spa) rn FROM cte c ) x WHERE rn = 1
PS: utilisez toujours des JOIN explicites au lieu d'implicites (Clause CROSS JOIN + WHERE). J'ai modifié la requête en conséquence.
vous pouvez utiliser les expressions de table communes
SELECT d.college, AVG(s.gpa) FROM huffman_departments d, huffman_students s WHERE s.majorcode = d.deptcode GROUP BY d.college order by 2 asc limit 1
si vous utilisez mysql
with cte0 as ( SELECT d.college, AVG(s.gpa) agpa FROM huffman_departments d, huffman_students s WHERE s.majorcode = d.deptcode GROUP BY d.college ) select * from cte0 c where c.college ( select ci.college from cte0 ci group by ci.college having min(ci.agpa) = a.gpa )
N'utilisez jamais de virgule dans la clause FROM
. Toujours utilisez une syntaxe appropriée, explicite, standard JOIN
.
Si vous recherchez une ligne, vous pouvez utiliser ORDER BY
et FETCH FIRST 1 ROW UNIQUEMENT
:
SELECT college, avg_gpa FROM (SELECT d.college, AVG(s.gpa) as avg_gpa, ROW_NUMBER() OVER (ORDER BY AVG(s.gpa)) as seqnum FROM huffman_departments d JOIN huffman_students s ON s.majorcode = d.deptcode GROUP BY d.college ) c WHERE seqnum = 1 ORDER BY AVG(s.gpa);
Si vous voulez voir plusieurs lignes en cas d'égalité, il existe plusieurs approches . Dans MySQL 8+, les fonctions de fenêtre sont probablement la méthode la plus simple. Dans les versions antérieures, la double agrégation peut être la plus simple:
SELECT avg_gpa, LISTAGG(college, ',') WITHIN GROUP (ORDER BY college) as colleges FROM (SELECT d.college, AVG(s.gpa) as avg_gpa FROM huffman_departments d JOIN huffman_students s ON s.majorcode = d.deptcode GROUP BY d.college ) c ORDER BY avg_gpa FETCH FIRST 1 ROW ONLY;
EDIT:
Les anciennes versions d'Oracle ne prennent pas en charge FETCH FIRST code >. Vous pouvez donc faire:
SELECT d.college, AVG(s.gpa) FROM huffman_departments d JOIN huffman_students s ON s.majorcode = d.deptcode GROUP BY d.college ORDER BY AVG(s.gpa) FETCH FIRST 1 ROW ONLY;
Première: "erreur à la ligne 7: la commande sql ne s'est pas correctement terminée."
Deuxième: "erreur à la ligne 9: la commande sql ne s'est pas correctement terminée."
En utilisant ce que vous avez déjà:
SELECT b.* FROM (SELECT d.college, AVG(s.gpa) avg_gpa FROM huffman_departments d, huffman_students s WHERE s.majorcode = d.deptcode GROUP BY d.college ) b WHERE b.avg_gpa = (SELECT MIN(a.avg_gpa) FROM ( SELECT d.college, AVG(s.gpa) avg_gpa FROM huffman_departments d, huffman_students s WHERE s.majorcode = d.deptcode GROUP BY d.college ) a);
Erreur à la ligne 5: identifiant invalide. J'ai changé avg_salary en avg_gpa. Aucun des deux n'a fonctionné.
J'ai trouvé une requête qui a fini par fonctionner. J'essaierai de le publier demain après avoir à nouveau sorti mon ordinateur portable. Merci pour l'aide. Je vais également essayer votre requête mise à jour demain.
Utilisez le bon
JOIN
. Il existe depuis plus de 25 ans.Essayez d'ajouter le Collège à votre requête externe
Votre requête interne ne renvoie qu'une seule ligne par université. Quel est le point de votre requête externe?