複数のレコードを生成する可能性のある結合テーブルから単一のレコードを取得する
-
03-07-2019 - |
質問
学生用のテーブルと登録用のテーブルがあります。学生は、アクティブまたは非アクティブにできる複数の登録レコードを持つことができます。
単一の学生レコードと、その学生がアクティブな登録を持っているかどうかについてのインジケータを持つセレクトを取得したい。
登録テーブルへの結合で学生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ステートメント)に置き換えます。
所属していません StackOverflow