当前位置:网站首页>5 minutes to understand MySQL - row to column

5 minutes to understand MySQL - row to column

2022-06-21 08:09:00 lxw1844912514

First , Creating table structure and importing test data SQL

# Create a table structure 
DROP TABLE IF EXISTS `t_gaokao_score`;
CREATE TABLE `t_gaokao_score`  (
  `id` int(0) NOT NULL AUTO_INCREMENT,
  `student_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT ' The student's name ',
  `subject` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT ' subject ',
  `score` double NULL DEFAULT NULL COMMENT ' achievement ',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
# Import test data 
INSERT INTO `t_gaokao_score` VALUES 
(1, ' Lin Leier ', ' Chinese language and literature ', 148),
(2, ' Lin Leier ', ' mathematics ', 150),
(3, ' Lin Leier ', ' English ', 147),
(4, ' Joe yingzi ', ' Chinese language and literature ', 121),
(5, ' Joe yingzi ', ' mathematics ', 106),
(6, ' Joe yingzi ', ' English ', 146),
(7, ' Fang Yifan ', ' Chinese language and literature ', 70),
(8, ' Fang Yifan ', ' mathematics ', 90),
(9, ' Fang Yifan ', ' English ', 59),
(10, ' Fang Yifan ', ' Extra points for Specialty ', 200),
(11, ' Chen ha ha ', ' Chinese language and literature ', 109),
(12, ' Chen ha ha ', ' mathematics ', 92),
(13, ' Chen ha ha ', ' English ', 80);

then , Let's take a look at our test table data and the expected query results .

# The official account is 【 Code farmer Programming Advanced notes 】
mysql> SELECT * FROM t_gaokao_score;
+----+--------------+--------------+-------+
| id | student_name | subject      | score |
+----+--------------+--------------+-------+
|  1 |  Lin Leier        |  Chinese language and literature          |   148 |
|  2 |  Lin Leier        |  mathematics          |   150 |
|  3 |  Lin Leier        |  English          |   147 |
|  4 |  Joe yingzi        |  Chinese language and literature          |   121 |
|  5 |  Joe yingzi        |  mathematics          |   106 |
|  6 |  Joe yingzi        |  English          |   146 |
|  7 |  Fang Yifan        |  Chinese language and literature          |    70 |
|  8 |  Fang Yifan        |  mathematics          |    90 |
|  9 |  Fang Yifan        |  English          |    59 |
| 10 |  Fang Yifan        |  Extra points for Specialty      |   200 |
| 11 |  Chen ha ha        |  Chinese language and literature          |   109 |
| 12 |  Chen ha ha        |  mathematics          |    92 |
| 13 |  Chen ha ha        |  English          |    80 |
+----+--------------+--------------+-------+
13 rows in set (0.00 sec)

Let's look at the results of our row column conversion :

efc78f7069bff7eea8c24f2a2fea62c0.png

One 、 Transfer line column SQL How to write it

Method 1 : Use case..when..then Conduct Transfer line column

# The official account is 【 Code farmer Programming Advanced notes 】
SELECT student_name,
    SUM(CASE `subject` WHEN ' Chinese language and literature ' THEN score ELSE 0 END) as ' Chinese language and literature ',
    SUM(CASE `subject` WHEN ' mathematics ' THEN score ELSE 0 END) as ' mathematics ',
    SUM(CASE `subject` WHEN ' English ' THEN score ELSE 0 END) as ' English ',
    SUM(CASE `subject` WHEN ' Extra points for Specialty ' THEN score ELSE 0 END) as ' Extra points for Specialty ' 
FROM t_gaokao_score 
GROUP BY student_name;

   If not used here SUM() Will be submitted to the sql_mode=only_full_group_by Related errors , Aggregate functions and group by Combined use or use distinct To solve the problem .

   Actually , added SUM() To be able to use GROUP BY according to student_name Grouping , every last student_name Corresponding subject=" Chinese language and literature " After all, there is only one record , therefore SUM() The value of is equal to that of the corresponding record score Value . Of course , It can also be replaced by MAX().

46ac8e51dfa90257782493f304d23ab7.png

Method 2 : Use IF() Conduct Transfer line column :

# The official account is 【 Code farmer Programming Advanced notes 】
SELECT student_name,
    SUM(IF(`subject`=' Chinese language and literature ',score,0)) as ' Chinese language and literature ',
    SUM(IF(`subject`=' mathematics ',score,0)) as ' mathematics ',
    SUM(IF(`subject`=' English ',score,0)) as ' English ',
    SUM(IF(`subject`=' Extra points for Specialty ',score,0)) as ' Extra points for Specialty ' 
FROM t_gaokao_score 
GROUP BY student_name;

   This method will IF(subject=' Chinese language and literature ',score,0) As a condition , adopt student_name Grouping , All after grouping subject=' Chinese language and literature ’ The record of score The fields go SUM() operation , If score If there is no value, the default value is 0. This way and case..when..then The principle of the method is the same , More concise than , It is recommended to use .

Two 、 If leadership @ you , Let you add the total sequence to the result set ?

Friendship tips : When we deal with row to column data in our work , Try to count the total 、 Average, etc. plus , Convenient for leaders to consult , Save him circulation BB you .

How to write it : utilize SUM(IF()) Generate columns ,WITH ROLLUP Generate summary columns and rows , And make use of IFNULL Display the summary row header as a total

# The official account is 【 Code farmer Programming Advanced notes 】
SELECT IFNULL(student_name,' total ') AS student_name,
    SUM(IF(`subject`=' Chinese language and literature ',score,0)) AS ' Chinese language and literature ',
    SUM(IF(`subject`=' mathematics ',score,0)) AS ' mathematics ',
    SUM(IF(`subject`=' English ',score,0)) AS ' English ',
    SUM(IF(`subject`=' Extra points for Specialty ',score,0)) AS ' Extra points for Specialty ',
    SUM(score) AS ' total ' 
FROM t_gaokao_score
GROUP BY student_name WITH ROLLUP;

Query results :

c3ed03e683651b64f48f3e996cf4249b.png

3、 ... and 、 Once again, the leadership is double. @ You need to change

   Let you convert the score into specific content display ( good 、 good 、 Ordinary 、 Bad ),430 Key universities with scores above ,400 Score more than one book ,350 Two or more copies ,350 Move bricks below , How to write ?

   Here we need case when nesting There you go , Look at the tall , It's just ordinary nesting . Find out the scores of each subject after grouping on the first floor , Replace it with grade on the second floor .

SELECT student_name,
MAX(  
        CASE subject  
        WHEN ' Chinese language and literature ' THEN  
            (  
                CASE  
                WHEN score - (select avg(score) from t_gaokao_score where subject=' Chinese language and literature ') > 20 THEN  
                    ' good '  
                WHEN score - (select avg(score) from t_gaokao_score where subject=' Chinese language and literature ') > 10 THEN  
                    ' good '  
                WHEN score - (select avg(score) from t_gaokao_score where subject=' Chinese language and literature ') >= 0 THEN  
                    ' Ordinary '  
                ELSE  
                    ' Bad '  
                END  
            )  
        END  
    ) as ' Chinese language and literature ', 
MAX(  
        CASE subject  
        WHEN ' mathematics ' THEN  
            (  
                CASE  
                WHEN score - (select avg(score) from t_gaokao_score where subject=' mathematics ') > 20 THEN  
                    ' good '  
                WHEN score - (select avg(score) from t_gaokao_score where subject=' mathematics ') > 10 THEN  
                    ' good '  
                WHEN score - (select avg(score) from t_gaokao_score where subject=' mathematics ') >= 0 THEN  
                    ' Ordinary '  
                ELSE  
                    ' Bad '  
                END  
            )  
        END  
    ) as ' mathematics ',
MAX(  
        CASE subject  
        WHEN ' English ' THEN  
            (  
                CASE  
                WHEN score - (select avg(score) from t_gaokao_score where subject=' English ') > 20 THEN  
                    ' good '  
                WHEN score - (select avg(score) from t_gaokao_score where subject=' English ') > 10 THEN  
                    ' good '  
                WHEN score - (select avg(score) from t_gaokao_score where subject=' English ') >= 0 THEN  
                    ' Ordinary '  
                ELSE  
                    ' Bad '  
                END  
            )  
        END  
    ) as ' English ',
SUM(score) as ' Total score ',
(CASE WHEN SUM(score) > 430 THEN ' Key universities '  
      WHEN SUM(score) > 400 THEN ' a copy '  
      WHEN SUM(score) > 350 THEN ' Two copies '  
      ELSE ' Move bricks at the construction site ' 
      END ) as ' result '
FROM t_gaokao_score 
GROUP BY student_name 
ORDER BY SUM(score) desc;

Let's take a look at the output :

fc1e67d02c520a2312dd403744c166ca.png

Okay ,SQL These are the above contents , If you have any questions, you can leave a message in the comment area !

48222a40894c5443426802e45a0b716f.png

原网站

版权声明
本文为[lxw1844912514]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/172/202206210803310642.html