[英]MySQL left join subquery null join
Ok, so I have a fairly detailed SQL query, I have 2 tables, the first table contains homework data. 好的,所以我有一个相当详细的SQL查询,我有2个表,第一个表包含作业数据。 The second table contains a record for each student in a class the homework is set for. 第二张表包含为该家庭作业设置的班级中每个学生的记录。
I want to count some data on the second table, where certain conditions are met, for example, how many students the homework was issued to, count how many students have returned homework, and count how many homeworks have been reviewed by the teacher. 我想在满足某些条件的第二张表上统计一些数据,例如,向多少学生发放了家庭作业,计算了多少学生归还了作业,还计算了老师复习了多少作业。
I'll post my query at the bottom of this post. 我将在本文的底部发布我的查询。
I'm using a subquery on 2 left joins. 我在2个左联接上使用子查询。 The subquery looks like this: 子查询如下所示:
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
In the example above, the student log table contains an index homework_id
which links back to the master homework table's unique index h.uid
. 在上面的示例中,学生日志表包含一个索引homework_id
,该索引链接回到主作业表的唯一索引h.uid
。
My problem is occuring when this scenario is valid: 这种情况有效时发生我的问题:
1) If COUNT(uid)
equals 0, homework_id is NULL
. 1)如果COUNT(uid)
等于0,则homework_id为NULL
。
2) The query produces the following result 2)查询产生以下结果
r2.homework_id | total_returned (COUNT(uid))
------------------+------------------------------
NULL | 0
My joins failing with the following error message: 我的联接失败,并显示以下错误消息:
Column 'homework_id' cannot be null - (r2 ON r2.homework_id (null) = h.uid)
I don't know how to solve this issue. 我不知道如何解决这个问题。 I initally had my subquery in the SELECT clause, but I want it in the LEFT JOINs. 我最初在SELECT子句中有我的子查询,但是我想在LEFT JOINs中有它。
My question is how can I make sure that r2.homework_id
is never null? 我的问题是如何确保r2.homework_id
永远不会为null? I've tried the following: 我尝试了以下方法:
where
clause in each join subquery to its associated ON
clause - Doesn't work 将每个联接子查询中的where
子句移至与其关联的ON
子句-不起作用 AND r2.homework_id IS NOT NULL
to the respective ON
clause - Doesn't work 尝试在各自的ON
子句中添加AND r2.homework_id IS NOT NULL
不起作用 AND COUNT(uid)>0
to the WHERE
clause in the join subquery - Doesn't work 尝试在连接子查询的WHERE
子句中添加AND COUNT(uid)>0
不起作用 I'm all out of ideas. 我全都没主意了。
Here's my whole query: 这是我的整个查询:
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
You don't really need sub-queries, much less three of them to get the data you're looking for. 您实际上并不需要子查询,只需更少的三个子查询即可获取所需的数据。 I believe the following will do the trick: 我相信以下将解决问题:
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
The main problem is that you're missing GROUP BY
clauses in your subqueries, so you're counting everything in the table that meets the WHERE
clauses, not counting them per-student. 主要问题是您的子查询中缺少GROUP BY
子句,因此您要对表中符合WHERE
子句的所有内容进行计数,而不是按学生对它们进行计数。 Also, all those tbl_homework_student_log
subqueries can be combined into a single query. 同样,所有这些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.