Domanda

Ho una tabella degli studenti e una tabella delle iscrizioni; uno studente potrebbe avere più record di iscrizione che possono essere attivi o inattivi.

Voglio ottenere una selezione con un singolo record di studente e un indicatore del fatto che quello studente abbia iscrizioni attive.

Ho pensato di farlo in un UDF in linea che utilizza l'ID studente in un join alla tabella di iscrizione, ma mi chiedo se esiste un modo migliore per farlo in una singola istruzione select.

La chiamata UDF potrebbe assomigliare a:

Select Student_Name,Student_Email,isEnrolled(Student_ID) from Student

Come potrebbe essere l'alternativa - con un'istruzione SQL -?

È stato utile?

Soluzione

select  Student_Name,
        Student_Email,
        (select count(*) 
         from Enrollment e 
         where e.student_id = s.student_id
        ) Number_Of_Enrollments 
 from Student e

otterrà il numero di iscrizioni, il che dovrebbe aiutare.

Altri suggerimenti

Perché non partecipare a una selezione secondaria? A differenza di altre soluzioni, questo non genera una sottoquery per ogni riga restituita, ma raccoglie i dati di iscrizione per tutti contemporaneamente. La sintassi potrebbe non essere del tutto corretta, ma dovresti avere l'idea.

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

La selezione dalle iscrizioni potrebbe anche essere ripetuta come funzione che restituisce una tabella su cui partecipare.

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

Modifica
Renze de Waal ha corretto il mio cattivo SQL!

Prova qualcosa del genere:

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

Penso che tu possa anche usare l'istruzione esistente nella selezione ma non positiva

cerca di evitare di usare udfs o subquery, sono dei killer delle prestazioni. banjolity sembra avere una buona soluzione altrimenti perché usa una tabella derivd invece di un UDF o sottoseleziona.

  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

Naturalmente, sostituisci la decodifica con una funzione utilizzata dal tuo database (o, un'istruzione case).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top