我正在尝试使用3个表并创建一个派生表,以将一些数据显示在一起,以显示完成百分比。
我正在使用的3个表是Student
,Tests
和Results
。我正在尝试将3个课程合并在一起,并创建一个派生表,其中以完成的测试百分比显示学生及其取得的进步。
作为一个例子,假设我要跟踪的3个学生都被分配了3个测试(在一个有数百个表的表中),我想看看他们走了多远。如果他们完成了所有3个测试,则派生表应存储100%的值。
StudentID SName
-----------------
1 Ken
2 Tom
3 Bob
TestID TName
----------------
11 Test 101
22 Test 102
33 Test 103
ResultsID TestID StudentID Passed
--------------------------------------
1 11 Tom 0
2 11 Bob 1
3 22 Bob 1
4 33 Bob 1
派生表:
StudentID SName %Completed
---------------------------
1 Ken 0%
2 Tom 0%
3 Bob 100%
我尝试了许多不同的方法,甚至不知道显示哪个方法,因为我觉得所有尝试都是完全错误的。有任何想法吗?抱歉,如果格式不好,这是我在这里的第一篇文章:)
谢谢!
答案 0 :(得分:0)
这似乎像join
和group by
一样:
select s.StudentID, s.SName,
sum(case when r.passed = 1 then 1.0 else 0 end) / t.cnt as ratio
from students s left join
results r
on s.studentid = r.studentid cross join
(select count(*) as cnt
from tests
) t
group by s.StudentID, s.SName, t.cnt;
答案 1 :(得分:0)
让所有可能的学生与测验组合。
可以交叉加入学生应通过的测试的子查询。
然后,可以将学生/考试的所有可能组合与实际结果结合在一起。
在那之后,这是一个平均的简单GROUP BY。
select
stu.StudentID,
stu.SName,
concat(AVG(coalesce(res.Passed,0)*100),'%') as [%Completed]
from Students as stu
cross join (
select TestID, TName
from Tests
where TestID in (11,22,33)
) as tst
left join Results as res on (res.StudentID = stu.StudentID and res.TestID = tst.TestID)
group by stu.StudentID, stu.SName
示例代码段:
-- Sample data
-- Using table variables for demonstration
declare @Students table (StudentID int identity(1,1) primary key, SName varchar(30));
insert into @Students (Sname) values
('Ken'),
('Tom'),
('Bob'),
('Jane');
declare @Tests table (TestID int primary key, TName varchar(30));
insert into @Tests (TestID, TName) values
(11,'Test 101'),
(22,'Test 102'),
(33,'Test 103');
declare @Results table (ResultsID int identity(1,1) primary key, TestID int, StudentID int, Passed bit);
insert into @Results (TestID, StudentID, Passed) values
(11,2,0),
(11,3,1),(22,3,1),(33,3,1),
(11,4,1);
-- Query
select
stu.StudentID,
stu.SName,
concat(AVG(coalesce(res.Passed,0)*100),'%') as [%Completed]
from @Students as stu
cross join (
select TestID, TName
from @Tests
where TestID in (11,22,33)
) as tst
left join @Results as res on (res.StudentID = stu.StudentID and res.TestID = tst.TestID)
group by stu.StudentID, stu.SName;
结果:
StudentID SName %Completed
--------- ----- ----------
1 Ken 0%
2 Tom 0%
3 Bob 100%
4 Jane 33%
答案 2 :(得分:0)
从数据中,我们看不到Ken已被分配给这3个测试,因此我们必须假定所有跟踪的学生都已分配给所有跟踪的测试。
这就是我要做的:
CROSS JOIN
并具有2个WHERE
条件)LEFT OUTER JOIN
确定结果(将NULL
替换为0)AVG
学生的时候计算GROUP BY
结果(广播到一个数字)这可以用单个SELECT
语句编写:
SELECT s.StudentID, s.SName, AVG(CAST(ISNULL(r.Passed, 0) as float)) AS Completed
FROM Students s CROSS JOIN Tests t
LEFT OUTER JOIN Results r ON t.TestID = r.TestID AND s.StudentID = r.StudentID
WHERE s.StudentID IN (1, 2, 3)
AND t.TestID IN (11, 22, 33)
GROUP BY s.StudentID, s.SName
Completed
值的格式(百分比)应在客户端应用程序中完成。