需求sql
以下兩張表student(學生表)、score(測試成績表)app
現須要統計:2015-03-10日以後,性別 age=1 的測試成績的 總分 與 平均分。oop
要求:使用一個SQL統計score表,將結果更新到student表的score_sum和score_avg字段中。性能
結果如圖:測試
實現:spa
若是咱們只須要更新一個字段,MYSQL和ORACLE語法是同樣的,在 set 後面跟一個子查詢便可,以下:.net
UPDATE student D
SET D.score_sum =
(
SELECT
SUM(B.score)
FROM score B
WHERE B.studentId = D.id
AND b.examTime >= '2015-03-10'
GROUP BY B.studentId
)
WHERE D.id =
(
SELECT
E.id FROM
(
SELECT
DISTINCT a.studentId AS id
FROM score A
WHERE A.examTime >= '2015-03-10'
) E
WHERE E.id = D.id
)
AND d.age = 1;blog
如今咱們須要同時更新2個字段,最不通過大腦思考的方法就是 「爲每一個 set 後面都跟一個子查詢」,ip
假如咱們要 set 十個字段或者更多字段呢?很顯然,這樣在性能上是很不合適的方法。get
同時更新多個字段在MYSQL和ORACLE中的方法是不同,MYSQL須要鏈接表,ORACLE使用 set(...) 便可
(看了下面的SQL你會發現,仍是ORACLE簡單易用、易懂)
1) MYSQL 實現咱們最終的需求,語句以下:
UPDATE student D
LEFT JOIN (SELECT
B.studentId,
SUM(B.score) AS s_sum,
ROUND(AVG(B.score),1) AS s_avg
FROM score B
WHERE b.examTime >= '2015-03-10'
GROUP BY B.studentId) C
ON (C.studentId = D.id)
SET D.score_sum = c.s_sum,
D.score_avg = c.s_avg
WHERE D.id =
(
SELECT
E.id FROM
(
SELECT
DISTINCT a.studentId AS id
FROM score A
WHERE A.examTime >= '2015-03-10'
) E
WHERE E.id = D.id
)
AND d.age = 1;
2) ORACLE 實現咱們最終的需求,語句以下:
UPDATE student D
SET (D.score_sum, D.score_avg) = (
SELECT
SUM(B.score) AS s_sum,
ROUND(AVG(B.score),1) AS s_avg
FROM score B
WHERE b.examTime >= '2015-03-10'
AND B.studentId = D.id
GROUP BY B.studentId
)
WHERE D.id =
(
SELECT
E.id FROM
(
SELECT
DISTINCT a.studentId AS id
FROM score A
WHERE A.examTime >= '2015-03-10'
) E
WHERE E.id = D.id
)
AND d.age = 1;
本文中用到的2個知識點:
一、更新多條記錄,每條記錄不一樣值。
二、同時更新多個字段的方法。
===== 將 age = 1 而且沒有測試成績的同窗給予默認值0,調整SQL以下 =====
UPDATE student D
LEFT JOIN (SELECT
B.studentId,
SUM(B.score) AS s_sum,
ROUND(AVG(B.score),1) AS s_avg
FROM score B
WHERE b.examTime >= '2015-03-10'
GROUP BY B.studentId) C
ON (C.studentId = D.id)
SET D.score_sum = IFNULL(c.s_sum,0),
D.score_avg = IFNULL(c.s_avg,0)
WHERE D.id =
(
SELECT
E.id FROM
(
SELECT
DISTINCT a.studentId AS id
FROM score A
##WHERE A.examTime >= '2015-03-10'
) E
WHERE E.id = D.id
)
AND d.age = 1;
結果以下:
Test SQL
[sql] view plain copy