數據庫 UPDATE多條記錄不一樣值,同時UPDATE多個字段

需求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

  1. /*  
  2. SQLyog Ultimate v10.00 Beta1  
  3. MySQL - 5.5.28 : Database - test  
  4. *********************************************************************  
  5. */  
  6.   
  7.   
  8. /*!40101 SET NAMES utf8 */;  
  9.   
  10. /*!40101 SET SQL_MODE=''*/;  
  11.   
  12. /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;  
  13. /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;  
  14. /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;  
  15. /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;  
  16. CREATE DATABASE /*!32312 IF NOT EXISTS*/`test` /*!40100 DEFAULT CHARACTER SET utf8 */;  
  17.   
  18. USE `test`;  
  19.   
  20. /*Table structure for table `score` */  
  21.   
  22. DROP TABLE IF EXISTS `score`;  
  23.   
  24. CREATE TABLE `score` (  
  25.   `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',  
  26.   `studentId` int(11) DEFAULT NULL COMMENT '學員ID',  
  27.   `subjectName` varchar(20) DEFAULT NULL COMMENT '科目名稱',  
  28.   `score` float DEFAULT NULL COMMENT '考試成績',  
  29.   `examTime` datetime DEFAULT NULL COMMENT '考試時間',  
  30.   PRIMARY KEY (`id`)  
  31. ) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8;  
  32.   
  33. /*Data for the table `score` */  
  34.   
  35. insert  into `score`(`id`,`studentId`,`subjectName`,`score`,`examTime`) values (1,1,'語文',70,'2015-02-26 18:11:39'),(2,1,'數學',80,'2015-03-26 18:11:50'),(3,1,'英語',76,'2015-04-26 18:11:56'),(4,1,'歷史',96,'2015-05-26 18:12:02'),(5,2,'語文\r\n數學\r\n英語\r\n歷史\r\n語文',84,'2015-02-26 18:11:39'),(6,2,'數學',56,'2015-03-26 18:11:50'),(7,2,'英語',86,'2015-04-26 18:11:56'),(8,2,'歷史',45,'2015-05-26 18:12:02'),(9,3,'語文',87,'2015-02-26 18:11:39'),(10,3,'數學',98,'2015-03-26 18:11:50'),(11,3,'英語',67,'2015-04-26 18:11:56'),(12,3,'歷史',86,'2015-05-26 18:12:02'),(13,4,'語文',97,'2015-02-26 18:11:39'),(14,4,'數學',68,'2015-03-26 18:11:50'),(15,4,'英語',79,'2015-04-26 18:11:56'),(16,4,'歷史',83,'2015-05-26 18:12:02'),(17,5,'語文',92,'2015-02-26 18:11:39'),(18,5,'數學',93,'2015-03-26 18:11:50'),(19,5,'英語',65,'2015-04-26 18:11:56'),(20,5,'歷史',88,'2015-05-26 18:12:02'),(21,6,'語文',87,'2015-01-05 18:48:48'),(22,6,'數學',67,'2015-01-05 18:48:48'),(23,6,'英語',99,'2015-01-05 18:48:48'),(24,6,'歷史',88,'2015-01-05 18:48:48');  
  36.   
  37. /*Table structure for table `student` */  
  38.   
  39. DROP TABLE IF EXISTS `student`;  
  40.   
  41. CREATE TABLE `student` (  
  42.   `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',  
  43.   `name` varchar(20) DEFAULT NULL COMMENT '姓名',  
  44.   `score_sum` varchar(20) DEFAULT NULL COMMENT '總成績',  
  45.   `score_avg` varchar(20) DEFAULT NULL COMMENT '平均成績',  
  46.   `age` int(11) DEFAULT NULL COMMENT '1男0女',  
  47.   PRIMARY KEY (`id`)  
  48. ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;  
  49.   
  50. /*Data for the table `student` */  
  51.   
  52. insert  into `student`(`id`,`name`,`score_sum`,`score_avg`,`age`) values (1,'小明','252','84',1),(2,'小王','187','62.3',1),(3,'莉莉','','',0),(4,'柱子','230','76.7',1),(5,'大毛','','',0),(6,'亮子','0','0',1);  
  53.   
  54. /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;  
  55. /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;  
  56. /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;  
  57. /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;  
相關文章
相關標籤/搜索