簡體   English   中英

MySQL左連接子查詢null連接

[英]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? 我嘗試了以下方法:

  • 從聯接子查詢中刪除了COUNT()函數,並將其移至主選擇子句-不能按預期工作
  • 將每個聯接子查詢中的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM