Oracle行转列Sql语句示例
-- 创建表
CREATE TABLE T_TEST_PIVOT(QUESTIONS_NAME VARCHAR(50),QUESTIONS_ID VARCHAR(50),SCORE NUMBER);
INSERT INTO T_TEST_PIVOT VALUES('13-16', '5F12FA99716F4E0B9C15F0715C1FC956', 10);
INSERT INTO T_TEST_PIVOT VALUES('17', 'A432D69066A34FA29F21607E82AB2770', 8);
INSERT INTO T_TEST_PIVOT VALUES('18', '8A7D1130EE074B2B92480B48D4EF28B3', 12);
INSERT INTO T_TEST_PIVOT VALUES('19', 'E287E2BDB959475FA888863BBC143E7A', 10);
INSERT INTO T_TEST_PIVOT VALUES('20', 'C55136B256074761AF582ADD20324CF1', 9);
INSERT INTO T_TEST_PIVOT VALUES('21', '26E96EB33FDB4D3687F48080ABF89243', 2.33);
INSERT INTO T_TEST_PIVOT VALUES('22', '0908C33717864EB9A5AC6B183A218CF2', 7);
COMMIT;
SELECT * FROM T_TEST_PIVOT
-- 分组查询
SELECT QUESTIONS_NAME
,SUM(SCORE) SCORE
FROM T_TEST_PIVOT
GROUP BY QUESTIONS_NAME
-- 行转列查询
SELECT * FROM
(SELECT QUESTIONS_NAME, SCORE FROM T_TEST_PIVOT)
PIVOT (SUM(SCORE) FOR QUESTIONS_NAME
IN ('13-16' "13-16", '17', '18', '19', '20', '21', '22'));
报表示例:
实现步骤
步骤1,得到某个考试科目ID的所有题(包含主客观题)所有给分序列
-- 得到某个考试科目ID的所有题(包含主客观题)所有给分序列
-- 客观题,列转行
SELECT * FROM (
SELECT CAST(SCORE AS DECIMAL(10,2)) SCORE_DETAIL
FROM (
SELECT T.QUESTIONS_ID,
T.EXAM_COURSE_ID,
T1.ROW_INDEX,
REGEXP_SUBSTR(T.FULL_SCORE ,'[^,]+',1,T1.ROW_INDEX) SCORE
FROM T_TPL_OBJECTIVE_QUESTIONS T,
(SELECT LEVEL ROW_INDEX FROM DUAL CONNECT BY LEVEL<=200) T1
WHERE T1.ROW_INDEX <= LENGTH(T.FULL_SCORE) - LENGTH(REPLACE(T.FULL_SCORE,',')) + 1
AND T.EXAM_COURSE_ID = 'D87C1D2C4102472499C80B676DECF4C0' ) M2 GROUP BY SCORE
UNION
SELECT M1.SCORE
FROM (
SELECT T2.QUESTIONS_ID
,T2.SCORE
,T3.SERIAL_NO
,COUNT(*) CNT1
FROM T_RVW_FINAL T2
INNER JOIN T_TPL_SUBJECTIVE_QUESTIONS T3 ON T2.EXAM_COURSE_ID = T3.EXAM_COURSE_ID AND T2.QUESTIONS_ID = T3.QUESTIONS_ID
WHERE T2.EXAM_COURSE_ID = 'D87C1D2C4102472499C80B676DECF4C0'
GROUP BY T2.QUESTIONS_ID,T2.SCORE,T3.SERIAL_NO
) M1 GROUP BY M1.SCORE ) L
步骤2,客观题
SELECT * FROM (
SELECT
T1.EXAM_COURSE_ID
,T6.ORG_ID
,T6.ORG_NAME
,T5.CLASS_ID
,T5.CLASS_NAME
,(CASE WHEN EXTRACT(MONTH FROM SYSDATE) >= 9
THEN EXTRACT(YEAR FROM SYSDATE) - REG_YEAR + 1
ELSE EXTRACT(YEAR FROM SYSDATE) - REG_YEAR END) || '年级' GRADE
,T1.QUESTIONS_ID
,T1.QUESTIONS_NAME
,T1.SCORE FULL_SCORE
,T1.SERIAL_NO
,T2.SCORE
,(SELECT COUNT(1) FROM V_RPT_COURSE_STUDENT V
WHERE V.EXAM_COURSE_ID = T1.EXAM_COURSE_ID
AND V.ORG_ID = T6.ORG_ID
AND V.CLASS_ID = T5.CLASS_ID) ACTUAL_CNT
,COUNT(1) SCORE_CNT -- 某道题某个分值的得分人数
,ROUND((COUNT(1) / (SELECT COUNT(1) FROM V_RPT_COURSE_STUDENT V
WHERE V.EXAM_COURSE_ID = T1.EXAM_COURSE_ID
AND V.ORG_ID = T6.ORG_ID
AND V.CLASS_ID = T5.CLASS_ID))* 100 ,2) AS SCORE_PRECENT -- 得分率
,MAX(M1.AVG_SCORE) AVG_SCORE
,MAX(M1.STDDEV_SCORE) STDDEV_SCORE
,1 QUESTION_TYPE
FROM T_TPL_OBJECTIVE_QUESTIONS T1
INNER JOIN V_RPT_OBJECTIVE_QUESTIONS T2 ON T1.EXAM_COURSE_ID = T2.EXAM_COURSE_ID AND T1.QUESTIONS_ID = T2.QUESTIONS_ID
INNER JOIN T_EMS_EXAM_STUDENT T3 ON T2.TEST_NO = T3.TEST_NO AND T2.EXAM_COURSE_ID = T3.EXAM_COURSE_ID
INNER JOIN T_BAS_STUDENT T4 ON T3.STUDENT_ID = T4.STUDENT_ID
INNER JOIN T_BAS_CLASS T5 ON T4.CLASS_ID = T5.CLASS_ID
INNER JOIN T_BAS_ORGANIZATION T6 ON T5.ORG_ID = T6.ORG_ID
INNER JOIN (SELECT
T1.EXAM_COURSE_ID
,T1.QUESTIONS_ID
,ROUND(AVG(T2.SCORE),2) AVG_SCORE
,ROUND(STDDEV(T2.SCORE),2) STDDEV_SCORE
FROM T_TPL_OBJECTIVE_QUESTIONS T1
INNER JOIN V_RPT_OBJECTIVE_QUESTIONS T2 ON T1.EXAM_COURSE_ID = T2.EXAM_COURSE_ID AND T1.QUESTIONS_ID = T2.QUESTIONS_ID
INNER JOIN T_EMS_EXAM_STUDENT T3 ON T2.TEST_NO = T3.TEST_NO AND T2.EXAM_COURSE_ID = T3.EXAM_COURSE_ID
INNER JOIN T_BAS_STUDENT T4 ON T3.STUDENT_ID = T4.STUDENT_ID
INNER JOIN T_BAS_CLASS T5 ON T4.CLASS_ID = T5.CLASS_ID
INNER JOIN T_BAS_ORGANIZATION T6 ON T5.ORG_ID = T6.ORG_ID
WHERE T1.EXAM_COURSE_ID = 'D87C1D2C4102472499C80B676DECF4C0'
AND T6.ORG_ID = '16AD9626CA8044CE81CDA692B896B600'
AND T5.CLASS_ID = '73B41F587651422089C8B7518168F4E8'
GROUP BY T1.EXAM_COURSE_ID
,T1.QUESTIONS_ID ) M1 ON T1.EXAM_COURSE_ID = M1.EXAM_COURSE_ID AND T1.QUESTIONS_ID = M1.QUESTIONS_ID
WHERE T1.EXAM_COURSE_ID = 'D87C1D2C4102472499C80B676DECF4C0'
AND T6.ORG_ID = '16AD9626CA8044CE81CDA692B896B600'
AND T5.CLASS_ID = '73B41F587651422089C8B7518168F4E8'
GROUP BY T1.EXAM_COURSE_ID
,T1.QUESTIONS_ID
,T1.QUESTIONS_NAME
,T1.SCORE
,T1.SERIAL_NO
,T2.SCORE
,T6.ORG_ID
,T6.ORG_NAME
,T5.CLASS_ID
,T5.CLASS_NAME
,T5.REG_YEAR
)
PIVOT (
-- 注意这里的写法;
SUM(SCORE_CNT) 人数
,SUM(SCORE_PRECENT) 得分率
FOR SCORE
IN ('0' "0"
,'0.5' "0.5"
,'1' "1"
,'1.5' "1.5"
,'2' "2"
,'2.5' "2.5"
,'3' "3"
,'3.5' "3.5"
,'4' "4"
,'4.5' "4.5"
,'5' "5"
,'6' "6"
,'6.5' "6.5"
,'7' "7")
)
步骤3,主观题
SELECT * FROM (
SELECT
T1.EXAM_COURSE_ID
,T6.ORG_ID
,T6.ORG_NAME
,T5.CLASS_ID
,T5.CLASS_NAME
,(CASE WHEN EXTRACT(MONTH FROM SYSDATE) >= 9
THEN EXTRACT(YEAR FROM SYSDATE) - REG_YEAR + 1
ELSE EXTRACT(YEAR FROM SYSDATE) - REG_YEAR END) || '年级' GRADE
,T1.QUESTIONS_ID
,T1.QUESTIONS_NAME
,T1.FULL_SCORE
,T1.SERIAL_NO
,T2.SCORE
,(SELECT COUNT(1) FROM V_RPT_COURSE_STUDENT V
WHERE V.EXAM_COURSE_ID = T1.EXAM_COURSE_ID
AND V.ORG_ID = T6.ORG_ID
AND V.CLASS_ID = T5.CLASS_ID) ACTUAL_CNT
,COUNT(1) SCORE_CNT -- 某道题某个分值的得分人数
,ROUND((COUNT(1) / (SELECT COUNT(1) FROM V_RPT_COURSE_STUDENT V
WHERE V.EXAM_COURSE_ID = T1.EXAM_COURSE_ID
AND V.ORG_ID = T6.ORG_ID
AND V.CLASS_ID = T5.CLASS_ID))* 100 ,2) AS SCORE_PRECENT -- 得分率
,MAX(M1.AVG_SCORE) AVG_SCORE
,MAX(M1.STDDEV_SCORE) STDDEV_SCORE
,2 QUESTION_TYPE
FROM T_TPL_SUBJECTIVE_QUESTIONS T1
INNER JOIN T_RVW_FINAL T2 ON T1.EXAM_COURSE_ID = T2.EXAM_COURSE_ID AND T1.QUESTIONS_ID = T2.QUESTIONS_ID
INNER JOIN T_EMS_EXAM_STUDENT T3 ON T2.TEST_NO = T3.TEST_NO AND T2.EXAM_COURSE_ID = T3.EXAM_COURSE_ID
INNER JOIN T_BAS_STUDENT T4 ON T3.STUDENT_ID = T4.STUDENT_ID
INNER JOIN T_BAS_CLASS T5 ON T4.CLASS_ID = T5.CLASS_ID
INNER JOIN T_BAS_ORGANIZATION T6 ON T5.ORG_ID = T6.ORG_ID
INNER JOIN (SELECT
T1.EXAM_COURSE_ID
,T1.QUESTIONS_ID
,ROUND(AVG(T2.SCORE),2) AVG_SCORE
,ROUND(STDDEV(T2.SCORE),2) STDDEV_SCORE
FROM T_TPL_SUBJECTIVE_QUESTIONS T1
INNER JOIN T_RVW_FINAL T2 ON T1.EXAM_COURSE_ID = T2.EXAM_COURSE_ID AND T1.QUESTIONS_ID = T2.QUESTIONS_ID
INNER JOIN T_EMS_EXAM_STUDENT T3 ON T2.TEST_NO = T3.TEST_NO AND T2.EXAM_COURSE_ID = T3.EXAM_COURSE_ID
INNER JOIN T_BAS_STUDENT T4 ON T3.STUDENT_ID = T4.STUDENT_ID
INNER JOIN T_BAS_CLASS T5 ON T4.CLASS_ID = T5.CLASS_ID
INNER JOIN T_BAS_ORGANIZATION T6 ON T5.ORG_ID = T6.ORG_ID
WHERE T1.EXAM_COURSE_ID = 'D87C1D2C4102472499C80B676DECF4C0'
AND T6.ORG_ID = '16AD9626CA8044CE81CDA692B896B600'
AND T5.CLASS_ID = '73B41F587651422089C8B7518168F4E8'
GROUP BY T1.EXAM_COURSE_ID
,T1.QUESTIONS_ID ) M1 ON T1.EXAM_COURSE_ID = M1.EXAM_COURSE_ID AND T1.QUESTIONS_ID = M1.QUESTIONS_ID
WHERE T1.EXAM_COURSE_ID = 'D87C1D2C4102472499C80B676DECF4C0'
AND T6.ORG_ID = '16AD9626CA8044CE81CDA692B896B600'
AND T5.CLASS_ID = '73B41F587651422089C8B7518168F4E8'
GROUP BY T1.EXAM_COURSE_ID
,T1.QUESTIONS_ID
,T1.QUESTIONS_NAME
,T1.FULL_SCORE
,T1.SERIAL_NO
,T2.SCORE
,T6.ORG_ID
,T6.ORG_NAME
,T5.CLASS_ID
,T5.CLASS_NAME
,T5.REG_YEAR
)
PIVOT (
-- 注意这里的写法;
SUM(SCORE_CNT) 人数
,SUM(SCORE_PRECENT) 得分率 FOR SCORE
IN ('0' "0"
,'0.5' "0.5"
,'1' "1"
,'1.5' "1.5"
,'2' "2"
,'2.5' "2.5"
,'3' "3"
,'3.5' "3.5"
,'4' "4"
,'4.5' "4.5"
,'5' "5"
,'6' "6"
,'6.5' "6.5"
,'7' "7")
)