문제

학생 테이블과 등록 테이블이 있습니다. 학생은 활동적이거나 비활성화 될 수있는 여러 등록 기록을 가질 수 있습니다.

나는 단일 학생 기록이있는 선택과 그 학생이 적극적인 등록을 가지고 있는지에 대한 지표를 얻고 싶습니다.

나는 등록 테이블에 가입하여 학생 ID를 사용하는 인라인 UDF 에서이 작업을 수행하는 것에 대해 생각했지만 단일 선택 문서에서 더 좋은 방법이 있는지 궁금합니다.

UDF 호출은 다음과 같은 것처럼 보일 수 있습니다.

Select Student_Name,Student_Email,isEnrolled(Student_ID) from Student

하나의 SQL 문으로 대안은 어떤 모습일까요?

도움이 되었습니까?

해결책

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

등록 수를 얻을 수 있습니다.

다른 팁

2 차 선택에 가입하지 않겠습니까? 다른 솔루션과 달리 이것은 반환 된 모든 행에 대해 하위 쿼리를 발사하지는 않지만 모든 사람의 등록 데이터를 한 번에 모두 모으고 있습니다. 구문이 정확하지는 않지만 아이디어를 얻어야합니다.

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

등록에서 선택한 것은 또한 당신이 가입 할 수있는 테이블을 반환하는 함수로 재정의 될 수 있습니다.

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

편집하다:
Renze de Waal은 내 나쁜 SQL을 수정했습니다!

다음과 같이 시도해보십시오.

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

Select에서 Exists 문을 사용할 수 있다고 생각하지만 긍정적이지는 않습니다.

UDF 또는 하위 쿼리를 사용하지 않으면 성능 킬러입니다. Banjolity는 UDF 또는 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

물론, Decode를 데이터베이스가 사용하는 함수 (또는 Case 문)로 바꾸십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top