一、行轉列
1.1、初始測試數據
表結構:TEST_TB_GRADE
Sql代碼:
1
2
3
4
5
6
7
|
create table TEST_TB_GRADE ( ID
NUMBER(10) not null , USER_NAME
VARCHAR2(20 CHAR ), COURSE
VARCHAR2(20 CHAR ), SCORE FLOAT ) |
初始數據如下圖:
insert into test_tb_grade values(1, 'aa', 'Math', 80.0);
insert into test_tb_grade values(2, 'aa', 'English', 90.0);
insert into test_tb_grade values(3, 'bb', 'Math', 70.0);
insert into test_tb_grade values(4, 'bb', 'English', 60.0);
commit;
1.2、 如果需要實現如下的查詢效果圖:
這就是最常見的行轉列,主要原理是利用decode函數、聚集函數(sum),結合group by分組實現的,具體的sql如下:
Sql代碼:
SELECT user_name,
SUM(DECODE(course, 'Math', score, NULL)) AS MATH,
SUM(DECODE(course, 'English', score, NULL)) AS ENGLISH
FROM test_tb_grade
GROUP BY user_name
ORDER BY user_name;
1.3、延伸
如果要實現對各門功課的不同分數段進行統計,效果圖如下:
具體的實現sql如下:
Sql代碼:
SELECT t2.SCORE_GP,
SUM(DECODE(t2.course,'Math', COUNTNUM,NULL)) AS MATH,
SUM(DECODE(t2.course,'English', COUNTNUM,NULL)) AS ENGLISH
FROM
(SELECT t.course,
CASE
WHEN t.score<60
THEN '00-60'
WHEN t.score>=60
AND t.score <80
THEN '60-80'
WHEN t.score>=80
THEN '80-100'
END AS SCORE_GP,
COUNT(t.score) AS COUNTNUM
FROM test_tb_grade t
GROUP BY t.course,
CASE
WHEN t.score<60
THEN '00-60'
WHEN t.score>=60
AND t.score <80
THEN '60-80'
WHEN t.score>=80
THEN '80-100'
END
ORDER BY t.course
) t2
GROUP BY t2.SCORE_GP
ORDER BY t2.SCORE_GP;
二、列轉行
1.1、初始測試數據
表結構: TEST_TB_GRADE2Sql代碼:
1
2
3
4
5
6
7
8
|
create table TEST_TB_GRADE2 ( ID
NUMBER(10) not null , USER_NAME
VARCHAR2(20 CHAR ), CN_SCORE FLOAT , MATH_SCORE FLOAT , EN_SCORE FLOAT ) |
初始數據如下圖:
insert into TEST_TB_GRADE2 values(1, 'aa', 50, 60, 70);
insert into TEST_TB_GRADE2 values(1, 'bb', 60, 70, 80);
insert into TEST_TB_GRADE2 values(1, 'cc', 80, 90, 100);
insert into TEST_TB_GRADE2 values(1, 'dd', 100, 90, 80);
commit;
1.2、 如果需要實現如下的查詢效果圖:
這就是最常見的列轉行,主要原理是利用SQL裏面的union,具體的sql語句如下:
Sql代碼:
SELECT user_name,
'CN_SCORE' AS COURSE,
CN_SCORE AS SCORE
FROM test_tb_grade2
UNION
SELECT user_name,
'MATH_SCORE' AS COURSE,
MATH_SCORE AS SCORE
FROM test_tb_grade2
UNION
SELECT user_name,
'EN_SCORE' AS COURSE,
EN_SCORE AS SCORE
FROM test_tb_grade2
ORDER BY user_name,COURSE;
也可以利用【insert all into ... select】來實現,首先需要先建一個表TEST_TB_GRADE3:
Sql代碼:
1
2
3
4
5
6
|
create table TEST_TB_GRADE3 ( USER_NAME
VARCHAR2(20 CHAR ), COURSE
VARCHAR2(20 CHAR ), SCORE FLOAT ) |
再執行下面的sql:
Sql代碼:
INSERT ALL
INTO test_tb_grade3
(
USER_NAME,
COURSE,
SCORE
)
VALUES
(
user_name,
'Chinese',
CN_SCORE
)
INTO test_tb_grade3
(
USER_NAME,
COURSE,
SCORE
)
VALUES
(
user_name,
'Math',
MATH_SCORE
)
INTO test_tb_grade3
(
USER_NAME,
COURSE,
SCORE
)
VALUES
(
user_name,
'English',
EN_SCORE
)
SELECT user_name, CN_SCORE, MATH_SCORE, EN_SCORE FROM test_tb_grade2;
COMMIT;
別忘記commit操作,然後再查詢TEST_TB_GRADE3,發現表中的數據就是列轉成行了。