2
votes

Requête SQL pour afficher la moyenne minimale avec le titre à l'aide de deux tables

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)


3 commentaires

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?


4 Réponses :


1
votes

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.


0 commentaires

1
votes

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
)


0 commentaires

1
votes

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;


2 commentaires

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."



0
votes

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);


2 commentaires

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.