2016-05-31 7 views
0

Ziel ist es, den jüngsten Schüler in einer bestimmten Klasse anzuzeigen. Ich habe den einen mit den GROUP BY- und HAVING-Klauseln erstellt, aber die vorgeschlagene Antwort verwendet sie nicht. Während es sinnvoll ist, wie ihre Antwort funktioniert, verstehe ich immer noch nicht, warum meine Antwort nicht funktioniert. Sollte es nicht dasselbe sein?Was ist der Unterschied zwischen den beiden SQL-Abfragen?

Mine druckt mehrere Zeilen von wahrscheinlich allen Schülern in der Tabelle ENROLLMENT. Es sollte dies nur tun, wenn ich wegen der GROUP BY die HAVING-Klausel weggelassen hätte. Aber warum macht es das immer noch, selbst wenn die HAVING-Klausel es dem Eliminieren von Gruppen, die die Bedingung nicht erfüllen, sagt?

select 
    studfname 
    || ' ' 
    || studlname as fullname, 
    studdob 
from 
    uni.student s, 
    uni.enrolment e 
where 
    s.studid = e.studid 
    and 
    e.unitcode = 'FIT1004' 
    and 
    studdob = 
    (
    select 
     min(studdob) 
    from 
     uni.student s, 
     uni.enrolment e 
    where 
     s.studid = e.studid 
     and 
     e.unitcode = 'FIT1004' 
) 
order by 
    s.studid; 

SELECT studfname|| ' ' ||studlname AS stud_name, studdob 
    FROM uni.student s, uni.enrolment e 
    WHERE e.studid = s.studid 
    AND unitcode = 'FIT1004' 
    GROUP BY studfname, studlname, studdob 
    HAVING studdob = min(studdob); 

Vielen Dank im Voraus!

Antwort

0

Sie fragen haben, Ihre Gruppe (Studfname, Studlname, Studdob) ist auf ihren Mindest-Studdob zu beschränken (das ist, was Ihre HAVING-Klausel tut). Da jedes Mitglied Ihrer Gruppe nur einen Studdob hat, ist dieser Studdob der gleiche wie der Min (Studdob) für dieses Mitglied der Gruppe.

Wenn Sie Ihre HAVING-Klausel ändern, um die Unterabfrage von der richtigen Antwort zu verwenden, wird es wie erwartet:

HAVING studdob = ( 
    select 
     min(birthdate) 
    from 
     pat_Patient s, 
     phy_Physician e 
    where 
     s.PCPPhysicianSID = e.PhysicianSID 
     and 
     e.PhysicianSID = 26665 
) 

Dies kann der eleganteste Ansatz als andere Lösungen nicht sein, aber Ihre Frage zu beantworten, dies ist der Grund, warum Ihre Abfrage nicht funktioniert, während die richtige ist.

+0

Ah ja. Ich sehe es jetzt. Ich dachte, die having-Klausel könnte Gruppen miteinander vergleichen. Gibt es keine andere Möglichkeit, Gruppen miteinander zu vergleichen? Anders als Unterabfragen. –

+0

Wenn Sie Gruppen miteinander vergleichen möchten, würde ich vorschlagen, eine temporäre Tabelle oder einen gemeinsamen Tabellenausdruck zu verwenden, um zuerst Ihre Gruppen einzurichten, und dann mit einer zweiten Abfrage danach abzufragen, um Ihren Vergleich/Filterung durchzuführen. IMO, temporäre Tabellen oder CTEs sind normalerweise leichter zu lesen, zu codieren und zu bearbeiten als korrelierte Unterabfragen. – Shoeless

0

GROUP BY kombiniert alle Ergebnisse mit dem gleichen Spaltenwert in eine einzelne Zeile (meistens verwendet, wenn Sie Summen, Durchschnittswerte usw. benötigen). Während HAVING ist eine Art von WHERE, die Sie nach dem Laden aller Ergebnisse Ihrer Abfrage verwenden können (eine Post-Abrufbedingung)

Keine von diesen erhalten Sie den jüngsten Schüler von sich. Ich bin mir nicht sicher, was Ihre Spaltennamen sind, aber hier wird eine Abfrage würde ich verwenden:

SELECT studentname, studentage, class 
FROM students S 
WHERE studentage = (select MIN(studentage) from students where class = s.class) 

es, alle Schüler wählt, die die youngests Alter ihrer Klasse für jedes Mitglied