0

私たちの学校では、生徒が優秀な場合、データベースに保存されている仮想ポンド(またはドル)が与えられます。

これは私の質問です:

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を使用してクエリを実行しているため、:textプレースホルダーを使用しています)。

親クエリのWHERE条件に関しては、少し問題があります。

それが言うところ:

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

total_poundsフィールドはサブクエリの列の結果ですが、クエリを実行すると、次の結果が表示され続けます。

Unknown column 'total_pounds' in 'where clause'

誰かがこれに対する解決策を知っていますか?

ありがとう

フィル

4

2 に答える 2

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
于 2012-12-18T14:05:35.593 に答える
1

サブクエリを回避しようとすることが「本当の」解決策かもしれません (テーブルと GROUP BY の結果を結合することは可能かもしれません)

とにかく、WHERE 句で「total_pounds」を参照できないため、簡単な解決策はサブクエリを繰り返すことです。これは醜いですが、クエリ オプティマイザーやサーバーのキャッシュ (有効な場合) が、各サブクエリの 2 回の実行を回避する可能性があります...

于 2012-12-18T12:23:20.643 に答える