熱線電話:13121318867

登錄
首頁精彩閱讀SQL經典面試題 - 行列轉換
SQL經典面試題 - 行列轉換
2017-05-27
收藏

SQL經典面試題 - 行列轉換

在我們的實際工作中,為了研發出功能完整、系統健壯的軟件,需要我們測試人員想法設法的去挑出軟件的問題,所以很多公司對測試人員的要求甚至高于開發人員,而通過SQL語句的編寫,測試人員可以去進行數據查詢、數據正確性完整性驗證、構造測試數據、或者行破壞測試或壓力測試。因此,作為一個測試人員,掌握SQL的重要性就不言而喻了。在我們的面試過程中,會碰到各種數據庫或者編寫SQL的面試題。
來看下面這道難倒眾生的經典面試題
面試題:行列轉換
檸檬班第30期學生要畢業了,他們Linux、MySQL、Java成績保存在數據表 tb_lemon_grade中,表中字段id,student_name,course,score分別表示成績id,學生姓名,課程名稱,課程成績,表中數據表1所示。請寫出一條SQL,將表1的數據變成表2的形式
id    學生姓名    課程名稱    課程成績
1    張三     Linux       85
2    張三         MySQL       92
3    張三         Java       87
4    李四       Linux       96
5    李四      MySQL       89
6    李四         Java       100
7    王五         Linux       91
8    王五         MySQL       83
9    王五        Java       98
表1
學生姓名    Linux    MySQL    Java
張三          85      92     87
李四          96      89     100
王五          91      83     98
表2
一:創建表
CREATE TABLE tb_lemon_grade (
 id INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
 student_name VARCHAR(20) DEFAULT NULL,
 course VARCHAR(20) DEFAULT NULL,
 score FLOAT DEFAULT '0');
二:初始化數據
INSERT INTO tb_lemon_grade (student_name, course, score) VALUES
("張三", "Linux", 85),
("張三", "MySQL", 92),
("張三", "Java", 87),
("李四", "Linux", 96),
("李四", "MySQL", 89),
("李四", "Java", 100),
("王五", "Linux", 91),
("王五", "MySQL", 83),
("王五", "Java", 98);
三:首先我們查詢出所有數據,這個結果和我們的圖1是一樣的
select * from  tb_lemon_grade;

四:使用常量列輸出我們的目標結構
可以看到結果已經和我們的圖二非常接近了

五:使用IF函數,替換我們的常量列,將成績賦值到對應行的對應列
SELECT student_name,
IF(COURSE = 'Linux',SCORE,0) 'Linux',
IF(COURSE = 'MySQL',SCORE,0) 'MySQL',
IF(COURSE = 'Java',SCORE,0) 'Java'
FROM tb_lemon_grade;
運行SQL,結果如下所示:

六:我們來分析這個結果集,
在原始結構中,每一行表示了某個同學某一個科的成績,以第一行為例,第一行是張三同學Linux的成績,所以我們結果集中Linux有成績為85,而其他兩列MySQL和Java作為常量列,成績為0。
再分析每個同學的成績的所有行,如下圖所示,每個方塊內包含行中,就有該同學這門課程的成績,并且該方塊內其余行的成績值為0。因此,不難想到,我們可以使用分組,通過分組提取出每科的成績

七:分組,使用MAX函數取出最大值
(因為其中只有一行成績為真實成績,其他行值為0,所以最大值就是真實成績)
SELECT student_name,
MAX(IF(COURSE = 'Linux',SCORE,0)) 'Linux',
MAX(IF(COURSE = 'MySQL',SCORE,0)) 'MySQL',
MAX(IF(COURSE = 'Java',SCORE,0)) 'Java'
FROM tb_lemon_grade
GROUP BY student_name;

八:也可以分組后,對每行數據進行求和,使用SUM函數,語句和結果如下:
SELECT student_name,
SUM(IF(COURSE = 'Linux',SCORE,0)) 'Linux',
SUM(IF(COURSE = 'MySQL',SCORE,0)) 'MySQL',
SUM(IF(COURSE = 'Java',SCORE,0)) 'Java'
FROM tb_lemon_grade
GROUP BY student_name;

九:既然使用IF語句可以達到效果,那使用CASE語句也是同樣的效果
分組,使用MAX聚合函數
SELECT student_name,
max(CASE COURSE when 'Linux' THEN SCORE ELSE 0 END) as 'Linux',
max(CASE COURSE when 'MySQL' THEN SCORE ELSE 0 END) as 'MySQL',
max(CASE COURSE when 'Java' THEN SCORE ELSE 0 END) as 'Java'
FROM tb_lemon_grade
GROUP BY student_name;
結果如下圖所示:


使用SUM,結果如下圖所示
SELECT student_name,
SUM(CASE COURSE when 'Linux' THEN SCORE ELSE 0 END) as 'Linux',
SUM(CASE COURSE when 'MySQL' THEN SCORE ELSE 0 END) as 'MySQL',
SUM(CASE COURSE when 'Java' THEN SCORE ELSE 0 END) as 'Java'
FROM tb_lemon_grade
GROUP BY student_name;

總結:
通過上面一步一步的分解,我們就完成了一個行轉列的SQL語句編寫,現在問題又來了,這種方式雖然能達到效果,但是如果課程多了,比如還有英語、數學、物理等等課程,是不是寫起來就筆記麻煩了?有沒有動態的方式,不管有多少課程,通過SQL就能一步到位呢?大家可以去嘗試下,

數據分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數據分析師資訊
更多

OK
客服在線
立即咨詢
日韩人妻系列无码专区视频,先锋高清无码,无码免费视欧非,国精产品一区一区三区无码
客服在線
立即咨詢