複数のレコードを生成する可能性のある結合テーブルから単一のレコードを取得する

StackOverflow https://stackoverflow.com/questions/608451

質問

学生用のテーブルと登録用のテーブルがあります。学生は、アクティブまたは非アクティブにできる複数の登録レコードを持つことができます。

単一の学生レコードと、その学生がアクティブな登録を持っているかどうかについてのインジケータを持つセレクトを取得したい。

登録テーブルへの結合で学生IDを使用するインラインUDFでこれを行うことを考えましたが、単一の選択ステートメントでそれを行うより良い方法があるかどうか疑問に思います。

UDF呼び出しは次のようになります。

Select Student_Name,Student_Email,isEnrolled(Student_ID) from Student

SQLステートメントが1つある場合の代替案はどのようなものですか?

役に立ちましたか?

解決

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

登録数を取得します。これは役立つはずです。

他のヒント

セカンダリセレクトに参加しませんか?他のソリューションとは異なり、これは返されるすべての行に対してサブクエリを起動するのではなく、全員の登録データを一度に収集します。構文は完全に正しくないかもしれませんが、あなたはアイデアを得る必要があります。

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ステートメントを使用することもできますが、ポジティブではありません

udfsやサブクエリの使用を避けるようにしてください。これらはパフォーマンスを低下させます。それ以外の場合、banjolityはUDFまたはサブセレクトの代わりに派生テーブルを使用するため、良い解決策があるようです。

  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