2016-05-09 5 views
2

3つのテーブルを結合するレポートページ用のSQLコードを作成しています。ここに私が書いた質問があります。テーブル結合でCOUNT関数を使用する

comm.CommandText = "SELECT Count(DISTINCT Courses.CourseID) AS CourseCount, Count(DISTINCT Students.StudentID) AS StudentCount, Count(Students.StartDate) AS StartCount, School.Name, School.StartDate, School.SchoolFees " + 
       "FROM Schools " + 
       "LEFT JOIN Courses ON (School.SchoolID = Courses.SchoolId) " + 
       "LEFT JOIN Students ON (School.SchoolID = Student.SchoolID) " + 
       "WHERE School.Active = 1 " + 
       "GROUP BY School.Name, School.StartDate, School.SchoolFees"; 

上記のクエリはうまくいきます。しかし、Student.StartDateが条件を満たす各学校のStudent.StartDateの数を表示したいと思います。ここで私が使用したいクエリです

SELECT Count(Students.StartDate) 
FROM Students 
WHERE Student.StartDate >= DATEADD(month, -1, GETDATE()); 

上記のクエリをメインクエリの一部として返信したいのですが、それを達成する方法がわかりません。どんな助けもありがとう。ありがとう

答えて

4

あなたが異なるテーブルから集計をしたい場合は、あなたがすべきを助け推測テーブルを結合して集計するのではなく、常に集約を最初に構築して、これらを代わりに結合します。あなたのケースでは、別個のIDを数えることによって問題を回避することができましたが、それは常に可能ではありません(つまり、合計や平均を探しているとき)。あなたは条件付きでCASE WHENと数えることができます。それは(おそらくそうである)、少なくとも一人の学生と1つのコースを持っているすべての学校のために保証されている場合は

SELECT 
    COALESCE(c.CourseCount, 0) AS CourseCount, 
    COALESCE(s.StudentCount, 0) AS StudentCount, 
    COALESCE(s.StartCount, 0) AS StartCount, 
    School.Name, 
    School.StartDate, 
    School.SchoolFees 
FROM Schools 
LEFT JOIN 
(
    SELECT SchoolID, COUNT(*) AS CourseCount 
    FROM Courses 
    GROUP BY SchoolID 
) c ON c.SchoolId = School.SchoolID 
LEFT JOIN 
(
    SELECT 
    SchoolID, 
    COUNT(*) AS StudentCount, 
    COUNT(CASE WHEN StartDate >= DATEADD(month, -1, GETDATE() THEN 1 END) as StartCount 
    FROM Students 
    GROUP BY SchoolID 
) s ON s.SchoolId = School.SchoolID 
WHERE School.Active = 1; 

、あなたが外側を変更することができ加わり、COALESCE式のように取り除くの内側に合流します。

+0

あなたの答えは非常に有益でした。私は新しいことを学びました。どうもありがとう。私は少し質問があります。 COALESCE式を取り除くと、「SELECT CourseCount、StudentCount .....」という意味になります。 – elfico

+0

@elfico:そうです。異なるテーブルからデータを選択する際には、テーブル修飾子を使用して、カラム名が十分説明できるようにする必要がある場合でも、カラムがどこにあるのかを示します: 'SELECT c.CourseCount、s.StudentCount、s.StartCount、...' –

0

条件付き集計でこれを行うことができます。ただ、SELECTにこれを追加します。

CASE WHENを使用して
SUM(CASE WHEN Student.StartDate >= DATEADD(month,-1, GETDATE()) THEN 1 ELSE 0 END) as RecentStudents 
+0

ありがとうございます。私はそれを試して、それは働いたが、合計は1未満だった。私は21を期待していたが、20を得た。@Kettnerの答えを使用し、正しい答えを得た。新しい考え方を学びました。ありがとう – elfico

0

、あなたがこの問題を解決することができ、

SELECT Count(DISTINCT Courses.CourseID) AS CourseCount, 
     Count(DISTINCT Students.StudentID) AS StudentCount, 
     Count(Students.StartDate) AS StartCount, 
     Sum(CASE WHEN Student.StartDate >= DATEADD(month,-1, GETDATE()) 
       THEN 1 ELSE 0 END) AS StartDateCount , 
     School.Name, School.StartDate, School.SchoolFees 
FROM Schools 
LEFT JOIN Courses ON (School.SchoolID = Courses.SchoolId) 
LEFT JOIN Students ON (School.SchoolID = Student.SchoolID) 
WHERE School.Active = 1 
GROUP BY School.Name, School.StartDate, School.SchoolFees 
+0

この回答ありがとうございます。私はそれを試して、それは働いたが、合計は1未満だった。私は21を期待していたが、20を得た。@Kettnerの答えを使用し、正しい答えを得た。新しい考え方を学びました。ありがとう。 – elfico

0

を、私はこれが

myConnect.Open(); 
     comm.CommandText = "SELECT Count(DISTINCT Courses.CourseID) AS CourseCount, Count(DISTINCT Students.StudentID) AS StudentCount, Count(Students.StartDate) AS StartCount, School.Name, School.StartDate, School.SchoolFees, " + 
     "(SELECT Count(stu.StartDate) FROM Students stu WHERE School.SchoolID = stu.SchoolID AND stu.StartDate >= DATEADD(month,-1, GETDATE())) AS CountStartDate" + // your count 
     "FROM Schools " + 
     "LEFT JOIN Courses ON (School.SchoolID = Courses.SchoolId) " + 
     "LEFT JOIN Students ON (School.SchoolID = Student.SchoolID) " + 
     "WHERE School.Active = 1 " + 
     "GROUP BY School.Name, School.StartDate, School.SchoolFees"; 
+0

それは仕事をしなかった。私は@kettnerの答えを使用していました。しかし、助けてくれてありがとう。 – elfico

関連する問題