2012-10-23 40 views
1

我有一個問題在SQL中,我試圖找出學生出席在一個註冊系統中的類我正在建設但它贏了「別讓我在子查詢中使用父列,SQL查詢選擇每名學生使用子查詢無法使用從父查詢行使用出勤

SELECT A.student_id, TRUNCATE((100 - ((100/B.reg_num) * C.abs_num)), 0) AS attendance FROM 
students A 
JOIN (
SELECT COUNT(*) AS reg_num 
FROM students 
JOIN seminargroup_student ON seminargroup_student.student_id = students.student_id 
JOIN seminar_group ON seminar_group.seminar_group_id = seminargroup_student.seminar_group_id 
JOIN modules ON modules.module_id = seminar_group.seminar_group_module_id 
JOIN register_seminar ON register_seminar.seminar_id = seminar_group.seminar_group_id 
JOIN registers ON registers.register_id = register_seminar.register_id 
WHERE modules.module_id =1 AND students.student_id = A.student_id 
) B 
JOIN (
SELECT COUNT(*) AS abs_num 
FROM students 
JOIN seminargroup_student ON seminargroup_student.student_id = students.student_id 
JOIN seminar_group ON seminar_group.seminar_group_id = seminargroup_student.seminar_group_id 
JOIN modules ON modules.module_id = seminar_group.seminar_group_module_id 
JOIN absence ON students.student_id = absence.student_id 
WHERE modules.module_id =1 AND students.student_id = A.student_id 
) C 

這將返回:#1054 - 未知列‘A.student_id’在‘where子句’

感謝您的幫助!

+0

您的樣品doen't包含「A.student_id」,並使用「學生作爲A」和「學生」。請張貼導致錯誤的代碼 – Nogard

+0

我無法在任何WHERE子句中找到A.student_id。它只在SELECT子句中。 –

+0

也沒有'ON'子句與外部查詢中的三個連接中的任何一個相關聯... – MatBailie

回答

0

嘗試重寫你的查詢:

SELECT students.student_id, TRUNCATE((100 - ((100/B.reg_num) * C.abs_num)), 0) AS attendance FROM 
students 
JOIN ( 
SELECT COUNT(*) AS reg_num 
FROM students A 
JOIN seminargroup_student ON seminargroup_student.student_id = A.student_id 
JOIN seminar_group ON seminar_group.seminar_group_id = seminargroup_student.seminar_group_id 
JOIN modules ON modules.module_id = seminar_group.seminar_group_module_id 
JOIN register_seminar ON register_seminar.seminar_id = seminar_group.seminar_group_id 
JOIN registers ON registers.register_id = register_seminar.register_id 
HAVING modules.module_id =1 AND students.student_id = A.student_id 
) B 
JOIN ( 
SELECT COUNT(*) AS abs_num 
FROM students A 
JOIN seminargroup_student ON seminargroup_student.student_id = A.student_id 
JOIN seminar_group ON seminar_group.seminar_group_id = seminargroup_student.seminar_group_id 
JOIN modules ON modules.module_id = seminar_group.seminar_group_module_id 
JOIN absence ON A.student_id = absence.student_id 
HAVING modules.module_id =1 AND students.student_id = A.student_id 
) C 

UPD:WHERE子句替換爲具有和別名移動的子查詢中。 由於在SELECT之前計算WHERE,可能會導致錯誤。

而且這些問題可以幫助你解決這個問題:
2. WHERE vs HAVING

+0

感謝您的回覆,該工作但只對第一個學生,每一行都拉出同樣的東西 –

+0

編輯我的答案。請看看這是否解決了您的問題 – Nogard

+0

JOIN中沒有ON子句?我不認爲這是有效的。 –

1

它不會讓我在子查詢中使用父列

一般來說,您不需要在FROM中的子查詢中引用父代。

相反,你只需要添加您的加盟領域的SELECTGROUP BY子句中的子查詢,然後加入

例如

SELECT students.student_id, 
     Truncate((100 - ((100/b.reg_num) * c.abs_num)), 0) AS attendance 
FROM students 
     JOIN (SELECT a.studentid, 
        Count(*) AS reg_num 
      FROM students A 
        JOIN seminargroup_student 
         ON seminargroup_student.student_id = A.student_id 
        JOIN seminar_group 
         ON seminar_group.seminar_group_id = 
         seminargroup_student.seminar_group_id 
        JOIN modules 
         ON modules.module_id = 
         seminar_group.seminar_group_module_id 
        JOIN register_seminar 
         ON register_seminar.seminar_id = 
         seminar_group.seminar_group_id 
        JOIN registers 
         ON registers.register_id = register_seminar.register_id 
      GROUP BY a.studentid) A 
     ON students.studentid = a.student.id 
     JOIN (SELECT a.studentid, 
        Count(*) AS abs_num 
      FROM students aA 
        JOIN seminargroup_student 
         ON seminargroup_student.student_id = a.student_id 
        JOIN seminar_group 
         ON seminar_group.seminar_group_id = 
         seminargroup_student.seminar_group_id 
        JOIN modules 
         ON modules.module_id = 
         seminar_group.seminar_group_module_id 
        JOIN absence 
         ON a.student_id = absence.student_id 
      GROUP BY a.studentid) b 
     ON students.studentid = b.student.id 

作爲一個側面說明,你不必做兩子查詢,如果您使用的是左聯接和做一個重複計數的PK區域,而不是對*

SELECT 
    A.student_id, 
    TRUNCATE((100 - ((100/counts.reg_num) * counts.abs_num)), 0) AS attendance 
FROM 
students A 
JOIN 
(SELECT 
    COUNT(DISTINCT absence.absence_id) AS abs_num , --OR whatever the PK is 
    COUNT(DISTINCT registers.regeister_id) as reg_num, 
    students.student_id 


FROM students 
     JOIN seminargroup_student 
     ON seminargroup_student.student_id = students.student_id 
     JOIN seminar_group 
     ON seminar_group.seminar_group_id = 
      seminargroup_student.seminar_group_id 
     JOIN modules 
     ON modules.module_id = seminar_group.seminar_group_module_id 

     LEFT JOIN register_seminar 
     ON register_seminar.seminar_id = seminar_group.seminar_group_id 
     LEFT JOIN registers 
     ON registers.register_id = register_seminar.register_id 


     LEFT JOIN absence 
     ON students.student_id = absence.student_id 
GROUP BY 
    students.student_id) COUNTS 
ON a.student_id = coutnts.student_ID  
+0

您的第二個建議是不可靠的,因爲可能存在迷你笛卡爾產品,這會歪曲結果。 「COUNT(DISTINCT)可能會解決這個問題,但我不確定。 –

+0

@AndriyM是的,它確實修復它。您可以比較此[SQL小提琴]的第一個和第二個結果(http://sqlfiddle.com/#!2/03b34/7)謝謝 –