2012-12-18 41 views
0

在我們學校,當學生好時,他們會得到一個存儲在數據庫中的虛擬磅(或美元)。Mysql參考子查詢導致父母在哪裏子句

這是我的查詢:

SELECT s.chosen_name, s.chosen_surname, s.regId, s.admission_number, 
    (
     SELECT SUM(a.pounds_amount) 
     FROM tbl_pounds_log a 
     WHERE a.student_id=l.student_id 
    ) AS total_pounds, 
    (
     SELECT SUM(b.pounds_amount) 
     FROM tbl_pounds_log b 
     WHERE b.student_id=l.student_id 
     AND b.staff_id=:staffId 
     AND b.action_timestamp>(UNIX_TIMESTAMP()-3600) 
    ) AS available_pounds 
FROM TBL_student s 
LEFT JOIN tbl_pounds_log l 
    ON l.student_id=s.admission_number 
WHERE ((s.chosen_name LIKE :termOne AND s.chosen_surname LIKE :termTwo) 
     OR (s.chosen_name LIKE :termThree AND s.chosen_surname LIKE :termFour)) 
    AND (total_pounds>=:lowerPoundLimit 
     AND total_pounds<=:upperPoundLimit) 
GROUP BY s.admission_number 
ORDER BY s.chosen_surname ASC, s.chosen_name ASC 
LIMIT 0,10 

(我使用PHP PDO來執行查詢因此:文本佔位符)。

當涉及到父查詢中的WHERE條件時,我遇到了一些問題。

凡說:

... AND (total_pounds>=:lowerPoundLimit and total_pounds<=:upperPoundLimit) 

的total_pounds場是子查詢的列結果,但是當我運行查詢它不斷想出:

Unknown column 'total_pounds' in 'where clause' 

有誰知道一個解決方案對此?

感謝

菲爾

回答

3

問題是當評估WHERE子句時別名尚不可用。這個問題應該通過移動從SELECT子句中的子查詢可以解決到JOIN條款是這樣的:

SELECT s.chosen_name, s.chosen_surname, s.regId, s.admission_number, 
     total_pounds.pound_amount as total_pounds, 
     available_pounds.pound_amount as available_pounds 
FROM TBL_student s 
LEFT JOIN 
    (SELECT student_id, SUM(pounds_amount) AS pound_amount 
    FROM tbl_pounds_log 
    GROUP BY student_id) AS total_pounds 
ON total_pounds.student_id = s.admission_number 
LEFT JOIN 
    (SELECT student_id, SUM(b.pounds_amount) AS pound_amount 
    FROM tbl_pounds_log 
    WHERE b.staff_id=:staffId 
    AND b.action_timestamp>(UNIX_TIMESTAMP()-3600) 
    GROUP BY student_id) as available_pounds 
ON available_pounds.student_id = s.admission_number 
WHERE ((s.chosen_name LIKE :termOne AND s.chosen_surname LIKE :termTwo) 
     OR (s.chosen_name LIKE :termThree AND s.chosen_surname LIKE :termFour)) 
    AND (total_pounds.pound_amount >= :lowerPoundLimit 
     AND total_pounds.pound_amount <= :upperPoundLimit) 
GROUP BY s.admission_number 
ORDER BY s.chosen_surname ASC, s.chosen_name ASC 
LIMIT 0,10 

它似乎也可以編寫查詢,而不子查詢:

SELECT s.chosen_name, s.chosen_surname, s.regId, s.admission_number, 
     SUM(tp.pounds_amount) AS total_pounds 
     SUM(ap.pounds_amount) AS available pounds 
FROM tbl_students s 
LEFT JOIN tbl_pounds_log tp 
ON tp.student_id = s.admission_number 
LEFT JOIN tbl_pounds_log ap 
ON ap.student_id = tp.student_id 
AND ap.staff_id = tp.staff_id 
AND ap.staff_id = :staffId 
AND ap.action_timestamp = tp.action_timestamp 
AND ap.action_timestamp > (UNIX_TIMESTAMP()-3600) 
WHERE s.chosen_name LIKE :termOne AND s.chosen_surname LIKE :termTwo 
OR s.chosen_name LIKE :termThree AND s.chosen_surname LIKE :termFour 
GROUP BY s.admission_number, s.name, s.regId, s.admission_number 
HAVING SUM(tp.pounds_amount) BETWEEN upperPoundLimit AND lowerPoundLimit 
ORDER BY s.chosen_surname, s.chosen_name 
LIMIT 0,10 
+0

非常感謝您的回覆,它的工作原理:) –

+0

這兩個查詢與返回結果有任何區別嗎?再次感謝:) –

+0

我認爲他們應該返回相同的結果,但缺乏數據我無法測試它們。 –

1

試圖避免子查詢可能是「真實」的解決方案(有可能加入表和GROUP BY結果)

無論如何,因爲你不能指到WHERE子句中的'total_pounds',一個簡單的解決方案是重複子查詢。這是醜陋的,但也許查詢優化器和/或您的服務器的緩存(如果啓用)將避免每個子查詢執行2次...