GROUP中COUNT个不同的表

时间:2016-05-04 01:22:45

标签: sql sql-server sql-server-2014

我有一张表,其中包含学校提供的课程列表。每个班级都可以有多个会话。每个班级都可以分配学生。

我需要做的是计算每个班级的所有课程,以及参加课程的学生人数。我做了第一点,但如果我加入学生分配表,我的计数将是错误的。

我想到了一些你可以使用的假SQL。

我坚持从Pupil链接表中有效地获取计数。

DECLARE @Class TABLE
(
    ClassID INT NOT NULL,
    ClassName VARCHAR(20) NOT NULL
)

INSERT INTO @Class VALUES (1, 'English')
INSERT INTO @Class VALUES (2, 'Maths')

DECLARE @ClassSession TABLE
(
    ClassSessionID INT NOT NULL,
    ClassID INT NOT NULL,
    Description VARCHAR(100) NOT NULL
)

INSERT INTO @ClassSession VALUES (1, 1, 'Basic English')
INSERT INTO @ClassSession VALUES (2, 1, 'Advanced English')
INSERT INTO @ClassSession VALUES (3, 1, 'Amazing English')
INSERT INTO @ClassSession VALUES (4, 2, 'Basic English')
INSERT INTO @ClassSession VALUES (5, 2, 'Basic English')

DECLARE @ClassPupil TABLE
(
    ClassPupilID INT NOT NULL,
    ClassID INT NOT NULL,
    PupilID INT NOT NULL -- FK to the Pupils table.
)

INSERT INTO @ClassPupil VALUES (1, 1, 1000) 
INSERT INTO @ClassPupil VALUES (2, 1, 1001) 
INSERT INTO @ClassPupil VALUES (3, 1, 1002) 
INSERT INTO @ClassPupil VALUES (4, 1, 1003) 
INSERT INTO @ClassPupil VALUES (5, 1, 1004) 

INSERT INTO @ClassPupil VALUES (6, 2, 1005) 
INSERT INTO @ClassPupil VALUES (7, 2, 1006) 
INSERT INTO @ClassPupil VALUES (8, 2, 1007) 


SELECT ClassName, COUNT(*) AS Sessions, '??' AS NumerOfPupils
FROM @Class c
INNER JOIN @ClassSession cs
ON cs.ClassID = c.ClassID
GROUP BY c.ClassID, c.ClassName

它可以用子查询完成吗?这是最好的方式吗?

3 个答案:

答案 0 :(得分:2)

每个班级都有两个独立的维度。您需要单独聚合它们:

SELECT c.ClassName, cs.Sessions, cp.Pupils
FROM @Class c INNER JOIN
     (SELECT ClassId, COUNT(*) as sessions
      FROM @ClassSession cs 
      GROUP BY ClassId
     ) cs
     ON cs.ClassID = c.ClassID INNER JOIN
     (SELECT ClassId, COUNT(*) as pupils
      FROM @ClassPupil cp
      GROUP BY ClassId
     ) cp
     ON cp.ClassId = c.ClassId;

答案 1 :(得分:2)

另一种方法是使用CROSS APPLY来计算学生人数:

SELECT 
    ClassName, COUNT(*) AS Sessions, cp.NumberOfPupils
FROM @Class c
INNER JOIN @ClassSession cs
    ON cs.ClassID = c.ClassID
CROSS APPLY (
    SELECT COUNT(*) AS NumberOfPupils
    FROM @ClassPupil
    WHERE
        ClassID = c.ClassID
) cp
GROUP BY c.ClassID, c.ClassName, cp.NumberOfPupils

答案 2 :(得分:0)

SELECT ClassName, COUNT(distinct cs.ClassSessionID) AS Sessions, /*'??'*/ count( distinct cp.PupilID) AS NumerOfPupils
FROM @Class c
INNER JOIN @ClassSession cs
ON cs.ClassID = c.ClassID
inner join @ClassPupil cp on c.ClassID=cp.ClassID
GROUP BY /*c.ClassID,*/ c.ClassName

count(distinct ...)解决(解决)问题 通常,这是(A - > B,C)问题。