父where子句中的Mysql引用子查询结果
在我们学校,当一个学生表现良好时,他们会得到一个虚拟的英镑(或美元),它存储在一个数据库中 这是我的疑问:父where子句中的Mysql引用子查询结果,mysql,subquery,Mysql,Subquery,在我们学校,当一个学生表现良好时,他们会得到一个虚拟的英镑(或美元),它存储在一个数据库中 这是我的疑问: 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 tot
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
有人知道这个问题的解决办法吗
谢谢
Phil试图避免子查询可能是“真正的”解决方案(可能会连接表并按结果分组)
无论如何,由于您不能在WHERE子句中引用“total_pounds”,因此一个简单的解决方案是重复子查询。这很难看,但可能查询优化器和/或服务器缓存(如果启用)会避免每个子查询执行2次…尝试避免子查询可能是“真正的”解决方案(可能会连接表并按结果分组)
无论如何,由于您不能在WHERE子句中引用“total_pounds”,因此一个简单的解决方案是重复子查询。这很难看,但可能查询优化器和/或服务器的缓存(如果启用)会避免每个子查询执行2次…问题是,在计算
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
问题是,在计算
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,
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