我有一个SELECT语句,用于学校的学生列表,它目前使用以下代码运行,但我发现每次计数需要1-2秒,对此数据库的大多数其他简单查询不到一半一秒钟,所以我觉得我在这里效率很低。有一个更好的方法吗? 1-2秒可能听起来不是很多,但在更详细的声明中我添加到下面 还要计算出现/缺席的主题等,所以当我在声明中包含所有内容时,它将花费近30秒来运行。
SELECT studentID AS sID, stu.name AS Name,
(
SELECT COUNT( * )
FROM attendance
WHERE ((sID = 1)
AND classdate < CURDATE( ))
) AS present,
(
SELECT COUNT( * )
FROM attendance
WHERE ((sID != 1)
AND classdate < CURDATE( ))
) AS absent
FROM attendance
INNER JOIN students AS stu ON attendance.studentID = stu.id
WHERE awayid != -1
GROUP BY sID
ORDER BY present ASC
---------------------------------------------
| sID | Name | present | absent |
| 1 | John | 28 | 2 |
| 2 | Richard | 26 | 4 |
| 3 | Harry | 22 | 8 |
| 4 | Sarah | 22 | 8 |
| 5 | Tanya | 20 | 10 |
| 6 | Nathan | 20 | 10 |
| 7 | Kate | 20 | 10 |
---------------------------------------------
答案 0 :(得分:1)
做一些假设,试试这个:
SELECT
studentID AS sID,
stu.name AS Name,
sum(a.sID = 1) as present,
sum(a.sID != 1) as absent
FROM students AS stu
JOIN attendance a ON a.studentID = stu.id
AND classdate < CURDATE( )
WHERE awayid != -1
GROUP BY 1, 2
ORDER BY present ASC
请注意,在mysql中,true为1
,false为0
,因此SUM(condition)
计算它的真实次数,从而避免繁琐地使用CASE
其他数据库要求。
答案 1 :(得分:1)
您可以使用条件聚合:
select studentID as sID, stu.name,
sum((sID = 1) AND classdate < CURDATE( )) as present,
sum((sID != 1) AND classdate < CURDATE( )) as absent
FROM attendance INNER JOIN
students AS stu
ON attendance.studentID = stu.id
WHERE awayid != -1
GROUP BY sID
ORDER BY present ASC;
但让我感到困惑的是在子查询中使用sID
。它不会引用外studentId
中的select
。我怀疑应该在那里使用另一个变量。 (并且,如果sid
中有attendance
,您为什么要在外部查询中调用studentID
sID
?)