我有一张表,其中包含学校提供的课程列表。每个班级都可以有多个会话。每个班级都可以分配学生。
我需要做的是计算每个班级的所有课程,以及参加课程的学生人数。我做了第一点,但如果我加入学生分配表,我的计数将是错误的。
我想到了一些你可以使用的假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
它可以用子查询完成吗?这是最好的方式吗?
答案 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)问题。