Erste aus verknüpften Tabellen einzelne Datensätze zurück, die mehrere Datensätze erzeugen kann
-
03-07-2019 - |
Frage
Ich habe einen Schülertisch und einen Zugang Tisch bekommt; ein Student könnte mehrere Einschreibung Aufzeichnungen hat, die aktiv oder inaktiv sein können.
Ich möchte ein wählen erhalten, die einen einzelnen Schüler Rekord hat und einen Indikator, ob die Schüler aktiv Einschreibungen hat.
Ich dachte über diese in einem Inline-UDF zu tun, dass die Schüler-ID in einem Join der Einschreibung Tabelle verwendet, aber ich frage mich, ob es ein besserer Weg, um es in einer einzigen Select-Anweisung zu tun.
Das UDF-Aufruf könnte so etwas wie folgt aussehen:
Select Student_Name,Student_Email,isEnrolled(Student_ID) from Student
Was könnte die Alternative - mit einer SQL-Anweisung - aussehen
Lösung
select Student_Name,
Student_Email,
(select count(*)
from Enrollment e
where e.student_id = s.student_id
) Number_Of_Enrollments
from Student e
wird die Anzahl der Einschreibungen erhalten, die helfen soll.
Andere Tipps
Warum nicht eine sekundäre auswählen? Im Gegensatz zu anderen Lösungen feuert dies nicht eine Unterabfrage für jede Zeile zurückgegeben, sondern sammelt die Registrierungsdaten für alle auf einmal. Die Syntax kann nicht ganz richtig sein, aber man sollte die Idee.
SELECT
s.student_name,
s.student_email,
IsNull( e.enrollment_count, 0 )
FROM
Students s
LEFT OUTER JOIN (
SELECT
student_id,
count(*) as enrollment_count
FROM
enrollments
WHERE
active = 1
GROUP BY
student_id
) e
ON s.student_id = e.student_id
Die Auswahl von Einschreibungen auch als Funktion nochmals gemacht werden könnten, die eine Tabelle zurückgibt für Sie verbinden auf.
CREATE FUNCTION getAllEnrollmentsGroupedByStudent()
RETURNS @enrollments TABLE
(
student_id int,
enrollment_count int
) AS BEGIN
INSERT INTO
@enrollments
(
student_id,
enrollment_count
) SELECT
student_id,
count(*) as enrollment_count
FROM
enrollments
WHERE
active = 1
GROUP BY
student_id
RETURN
END
SELECT
s.student_name,
s.student_email,
e.enrollment_count
FROM
Students s
JOIN
dbo.getAllEnrollmentsGroupedByStudent() e
ON s.student_id = e.student_id
Bearbeiten
Renze de Waal korrigiert meine schlechte SQL!
Versuchen Sie etwas wie folgt aus:
SELECT Student_Name, Student_Email, CAST((SELECT TOP 1 1 FROM Enrollments e WHERE e.student_id=s.student_id) as bit) as enrolled FROM Student s
Ich glaube, Sie können auch mit der Aussage in der Auswahl aber nicht positiv existieren
versuchen Sie es mit udfs oder Unterabfragen zu vermeiden, sie Performance-Killer sind. banjolity scheint sonst gute Lösung havea, weil es eine derivd Tabelle anstelle eines UDF oder subselect verwendet.
select students.name,
decode(count(1), 0, "no enrollments", "has enrollments")
from students, enrollments
where
students.id = enrollments.sutdent_id and
enrollments.is_active = 1 group by students.name
Natürlich ersetzen Sie die decode mit einer Funktion Ihrer Datenbank verwendet (oder eine Fall-Anweisung).