[英]MySQL left join subquery null join
好的,所以我有一个相当详细的SQL查询,我有2个表,第一个表包含作业数据。 第二张表包含为该家庭作业设置的班级中每个学生的记录。
我想在满足某些条件的第二张表上统计一些数据,例如,向多少学生发放了家庭作业,计算了多少学生归还了作业,还计算了老师复习了多少作业。
我将在本文的底部发布我的查询。
我在2个左联接上使用子查询。 子查询如下所示:
LEFT JOIN (
SELECT homework_id, COUNT(uid) AS total_returned
FROM tbl_homework_student_log
WHERE homework_completed = 1
) r2 ON r2.homework_id = h.uid
在上面的示例中,学生日志表包含一个索引homework_id
,该索引链接回到主作业表的唯一索引h.uid
。
这种情况有效时发生我的问题:
1)如果COUNT(uid)
等于0,则homework_id为NULL
。
2)查询产生以下结果
r2.homework_id | total_returned (COUNT(uid))
------------------+------------------------------
NULL | 0
我的联接失败,并显示以下错误消息:
Column 'homework_id' cannot be null - (r2 ON r2.homework_id (null) = h.uid)
我不知道如何解决这个问题。 我最初在SELECT子句中有我的子查询,但是我想在LEFT JOINs中有它。
我的问题是如何确保r2.homework_id
永远不会为null? 我尝试了以下方法:
where
子句移至与其关联的ON
子句-不起作用 ON
子句中添加AND r2.homework_id IS NOT NULL
不起作用 WHERE
子句中添加AND COUNT(uid)>0
不起作用 我全都没主意了。
这是我的整个查询:
SELECT h.uid, h.class_id, h.homework_details, h.require_upload_return,
CONCAT(u.surname, ', ', u.forename) AS teacher_name,
DATE_FORMAT(h.set_date, '%D %M %Y') AS set_date_DMY,
DATE_FORMAT(h.set_date, '%b %e, %Y') AS set_date_beY,
UNIX_TIMESTAMP(h.set_date) AS set_date_timestamp,
DATE_FORMAT(h.due_date, '%D %M %Y') AS due_date_DMY,
DATE_FORMAT(h.due_date, '%b %e, %Y') AS due_date_beY,
UNIX_TIMESTAMP(h.due_date) AS due_date_timestamp,
IF(h.due_date<=DATE(NOW()), 1, 0) AS homework_due,
r1.total_issues,
IF(r2.total_returned IS NULL, 0, r2.total_returned) AS total_returned,
IF(h.due_date<=DATE(NOW()), r1.total_issues, IF(r2.total_returned IS NULL, 0, r2.total_returned)) AS waiting_review,
h.resource_file
FROM tbl_homework h
INNER JOIN tbl_users u
ON u.uid = h.teacher_id
INNER JOIN (
SELECT homework_id, COUNT(uid) AS total_issues
FROM tbl_homework_student_log
) r1 ON r1.homework_id = h.uid
LEFT JOIN (
SELECT uid, homework_id, COUNT(uid) total_returned
FROM tbl_homework_student_log
WHERE homework_completed = 1
) r2 ON r2.homework_id = h.uid
LEFT JOIN (
SELECT homework_id, COUNT(uid) waiting_review
FROM tbl_homework_student_log
WHERE seen_by_issuer = 0
) r3 ON r3.homework_id = h.uid
WHERE h.teacher_id = ?
AND h.set_date>=DATE_SUB(NOW(), INTERVAL 10 DAY)
AND h.homework_template = 0
ORDER BY h.class_id ASC,
h.set_date ASC
您实际上并不需要子查询,只需更少的三个子查询即可获取所需的数据。 我相信以下将解决问题:
SELECT h.uid,h.class_id, h.homework_details, h.require_upload_return,
CONCAT(u.surname, ', ', u.forename) AS teacher_name,
DATE_FORMAT(h.set_date, '%D %M %Y') AS set_date_DMY,
DATE_FORMAT(h.set_date, '%b %e, %Y') AS set_date_beY,
UNIX_TIMESTAMP(h.set_date) AS set_date_timestamp,
DATE_FORMAT(h.due_date, '%D %M %Y') AS due_date_DMY,
DATE_FORMAT(h.due_date, '%b %e, %Y') AS due_date_beY,
UNIX_TIMESTAMP(h.due_date) AS due_date_timestamp,
IF(h.due_date<=DATE(NOW()), 1, 0) AS homework_due,
COUNT(*) AS total_issues,
SUM(IF(l.homework_completed, 1, 0)) AS total_returned,
SUM(IF(l.seen_by_issuer = 0, 1, 0)) AS waiting_review,
h.resource_file
FROM tbl_homework h
INNER JOIN tbl_users u ON u.uid = h.teacher_id
INNER JOIN tbl_homework_student_log l ON h.uid = l.homework_id
WHERE h.teacher_id = ?
AND h.set_date>=DATE_SUB(NOW(), INTERVAL 10 DAY)
AND h.homework_template = 0
GROUP BY h.uid
ORDER BY h.class_id ASC,
h.set_date ASC
主要问题是您的子查询中缺少GROUP BY
子句,因此您要对表中符合WHERE
子句的所有内容进行计数,而不是按学生对它们进行计数。 同样,所有这些tbl_homework_student_log
子查询都可以合并为一个查询。
SELECT h.uid, h.class_id, h.homework_details, h.require_upload_return,
CONCAT(u.surname, ', ', u.forename) AS teacher_name,
DATE_FORMAT(h.set_date, '%D %M %Y') AS set_date_DMY,
DATE_FORMAT(h.set_date, '%b %e, %Y') AS set_date_beY,
UNIX_TIMESTAMP(h.set_date) AS set_date_timestamp,
DATE_FORMAT(h.due_date, '%D %M %Y') AS due_date_DMY,
DATE_FORMAT(h.due_date, '%b %e, %Y') AS due_date_beY,
UNIX_TIMESTAMP(h.due_date) AS due_date_timestamp,
IF(h.due_date<=DATE(NOW()), 1, 0) AS homework_due,
r.total_issues,
IFNULL(r.total_returned, 0) AS total_returned,
IF(h.due_date<=DATE(NOW()), r.total_issues, IFNULL(r.waiting_review, 0)) AS waiting_review,
h.resource_file
FROM tbl_homework h
INNER JOIN tbl_users u
ON u.uid = h.teacher_id
INNER JOIN (
SELECT homework_id, COUNT(*) AS total_issues
SUM(homework_completed = 1) AS total_returned,
SUM(seen_by_issuer = 0) AS waiting_review
FROM tbl_homework_student_log
GROUP BY homework_id
) r ON r.homework_id = h.uid
WHERE h.teacher_id = ?
AND h.set_date>=DATE_SUB(NOW(), INTERVAL 10 DAY)
AND h.homework_template = 0
ORDER BY h.class_id ASC,
h.set_date ASC
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.