Pergunta

Eu tenho uma mesa de estudante e uma mesa de inscrição; um estudante pode ter vários registros de inscrição que pode ser ativo ou inativo.

Eu quero ter uma escolha que tem um único registro de estudante e um indicador para saber se esse aluno tem inscrições ativas.

Eu pensei em fazer isso em um UDF embutido que usa a identificação do aluno em uma junção com a tabela de inscrição, mas gostaria de saber se há uma maneira melhor de fazê-lo em uma única instrução SELECT.

A chamada UDF poderia ser algo como:

Select Student_Name,Student_Email,isEnrolled(Student_ID) from Student

O que pode a alternativa - com uma instrução SQL -? Parecido com

Foi útil?

Solução

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

obterá o número de matrículas, o que deve ajudar.

Outras dicas

Por que não juntar a um seleto secundária? Ao contrário de outras soluções, isso não está disparando uma subconsulta para cada linha retornada, mas reúne os dados de matrícula para todos de uma só vez. A sintaxe pode não ser muito correto, mas você deve ficar com a ideia.

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

O seleto de matrículas também poderia ser refeito como uma função que retorna uma tabela para você participar na.

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

Editar:
Renze de Waal corrigido meu mau SQL!

Tente algo parecido com isto:

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

Eu acho que você também pode usar a declaração existe no seleto, mas não positivo

tentar evitar o uso udfs ou subqueries, eles são assassinos de desempenho. banjolity parece solução havea boa de outra forma, porque ele usa uma tabela derivd em vez de uma UDF ou subselect.

  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

É claro, substitua a decodificação com uma função de seus usos de banco de dados (ou, uma instrução CASE).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top