gpt4 book ai didi

MySQL左连接子查询空连接

转载 作者:行者123 更新时间:2023-11-29 06:39:31 24 4
gpt4 key购买 nike

好的,所以我有一个相当详细的 SQL 查询,我有 2 个表,第一个表包含作业数据。第二个表包含作业所针对的类(class)中每个学生的记录。

我想统计第二张表的一些数据,在满足一定条件的情况下,比如作业发给了多少学生,统计有多少学生交回了作业,统计了多少作业被批改了老师。

我会在这篇文章的底部发布我的查询。

我在 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 JOIN 中。

我的问题是如何确保 r2.homework_id 永远不会为空?我尝试了以下方法:

  • 从连接子查询中删除了 COUNT() 函数并将它们移至主选择子句 - 未按预期工作
  • 将每个连接子查询中的 where 子句移动到其关联的 ON 子句 - 不起作用
  • 尝试将 AND r2.homework_id IS NOT NULL 添加到相应的 ON 子句 - 不起作用
  • 尝试将 AND COUNT(uid)>0 添加到连接子查询的 WHERE 子句中 - 不起作用

我完全没有想法。

这是我的整个查询:

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

最佳答案

主要问题是您的子查询中缺少 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

关于MySQL左连接子查询空连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22329297/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com