Oracle列转行_看自SQL经典模式-列转行

需求:
找出一些课程, 这些课程是由1位以上 男老师教,并且他们的级别大于3,并且他们年龄在40以下的。

课程表: 每门课程由5位老师教,要求包含老师的信息,以及一些课程的信息
create table course (id int, name varchar(100), teacher1 int,teacher2 int,teacher3 int, teacher4 int, teacher5 int);

insert into course values (1,concat('Course_',round(sys.dbms_random.value(1,300))),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)));
insert into course values (2,concat('Course_',round(sys.dbms_random.value(1,300))),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)));
insert into course values (3,concat('Course_',round(sys.dbms_random.value(1,300))),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)));
insert into course values (4,concat('Course_',round(sys.dbms_random.value(1,300))),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)));
insert into course values (5,concat('Course_',round(sys.dbms_random.value(1,300))),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)));
insert into course values (6,concat('Course_',round(sys.dbms_random.value(1,300))),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)));
insert into course values (7,concat('Course_',round(sys.dbms_random.value(1,300))),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)));
insert into course values (8,concat('Course_',round(sys.dbms_random.value(1,300))),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)));
insert into course values (9,concat('Course_',round(sys.dbms_random.value(1,300))),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)));
insert into course values (10,concat('Course_',round(sys.dbms_random.value(1,300))),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)));
insert into course values (11,concat('Course_',round(sys.dbms_random.value(1,300))),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)));
insert into course values (12,concat('Course_',round(sys.dbms_random.value(1,300))),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)),round(sys.dbms_random.value(1,14)));

-- DELETE TABLE course;
--DROP TABLE course;
COMMIT;
SELECT * FROM course a ORDER BY A.NAME;

老师表: 记录了每个老师的年龄,级别,性别
这里需要说明: LEVEL 在Oracle 中是keyword,所以需要替换,这里我替换成了Scale
create table teacher(id int, age int,scale int, gender int);
insert into teacher values (1,round(SYS.DBMS_RANDOM.value(30,50)),round(SYS.DBMS_RANDOM.value(1,10)),round(SYS.DBMS_RANDOM.value(0,1)));
insert into teacher values (2, round(SYS.DBMS_RANDOM.value(30,50)),round(SYS.DBMS_RANDOM.value(1,10)), round(SYS.DBMS_RANDOM.value(0,1)));
insert into teacher values (3, round(SYS.DBMS_RANDOM.value(30,50)),  round(SYS.DBMS_RANDOM.value(1,10)), round(SYS.DBMS_RANDOM.value(0,1)));
insert into teacher values (4, round(SYS.DBMS_RANDOM.value(30,50)),  round(SYS.DBMS_RANDOM.value(1,10)), round(SYS.DBMS_RANDOM.value(0,1)));
insert into teacher values (5, round(SYS.DBMS_RANDOM.value(30,50)),  round(SYS.DBMS_RANDOM.value(1,10)), round(SYS.DBMS_RANDOM.value(0,1)));
insert into teacher values (6, round(SYS.DBMS_RANDOM.value(30,50)),  round(SYS.DBMS_RANDOM.value(1,10)), round(SYS.DBMS_RANDOM.value(0,1)));
insert into teacher values (7, round(SYS.DBMS_RANDOM.value(30,50)),  round(SYS.DBMS_RANDOM.value(1,10)), round(SYS.DBMS_RANDOM.value(0,1)));
insert into teacher values (8, round(SYS.DBMS_RANDOM.value(30,50)),  round(SYS.DBMS_RANDOM.value(1,10)), round(SYS.DBMS_RANDOM.value(0,1)));
insert into teacher values (9, round(SYS.DBMS_RANDOM.value(30,50)),  round(SYS.DBMS_RANDOM.value(1,10)), round(SYS.DBMS_RANDOM.value(0,1)));
insert into teacher values (10, round(SYS.DBMS_RANDOM.value(30,50)),  round(SYS.DBMS_RANDOM.value(1,10)), round(SYS.DBMS_RANDOM.value(0,1)));
insert into teacher values (11, round(SYS.DBMS_RANDOM.value(30,50)),  round(SYS.DBMS_RANDOM.value(1,10)), round(SYS.DBMS_RANDOM.value(0,1)));
insert into teacher values (12, round(SYS.DBMS_RANDOM.value(30,50)),  round(SYS.DBMS_RANDOM.value(1,10)), round(SYS.DBMS_RANDOM.value(0,1)));
insert into teacher values (13, round(SYS.DBMS_RANDOM.value(30,50)),  round(SYS.DBMS_RANDOM.value(1,10)), round(SYS.DBMS_RANDOM.value(0,1)));
insert into teacher values (14, round(SYS.DBMS_RANDOM.value(30,50)),  round(SYS.DBMS_RANDOM.value(1,10)), round(SYS.DBMS_RANDOM.value(0,1)));

COMMIT;
--------
SELECT * FROM TEACHER B ORDER BY B.ID;

列转行需要一个工具表pivot,里面只有一列,存多少,取决于你有多少个列需要转成行, 我们这个例子是5(5位老师嘛)
CREATE TABLE pivot(id int);
INSERT INTO PIVOT VALUES(1);
INSERT INTO PIVOT VALUES(2);
INSERT INTO PIVOT VALUES(3);
INSERT INTO PIVOT VALUES(4);
INSERT INTO PIVOT VALUES(5);
COMMIT;
我勒个去!看到了表,才看见什么叫做 一条记录复制5行。拿课程名为:Course_114的为例
 
步骤一:得到一个临时表
SELECT C.ID ,C.NAME,
       CASE
       WHEN P.ID = 1 THEN C.TEACHER1
       WHEN P.ID = 2 THEN C.TEACHER2
       WHEN P.ID = 3 THEN C.TEACHER3
       WHEN P.ID = 4 THEN C.TEACHER4
       WHEN P.ID = 5 THEN C.TEACHER5
       ELSE 0
       END
       AS teacherID
FROM COURSE C,PIVOT P
WHERE C.NAME = 'Course_114'

我比较笨,看到图(数据)了之后才发现,真的看到了是行转列耶!
步骤二: 在临时表的基础上,再进行过滤(男老师教gender=0,并且他们的级别大于2,并且他们年龄在41),得到合适的结果集
SELECT TEMP.NAME
FROM(
SELECT C.ID ,C.NAME,
       CASE
       WHEN P.ID = 1 THEN C.TEACHER1
       WHEN P.ID = 2 THEN C.TEACHER2
       WHEN P.ID = 3 THEN C.TEACHER3
       WHEN P.ID = 4 THEN C.TEACHER4
       WHEN P.ID = 5 THEN C.TEACHER5
       ELSE 0
       END
       AS teacherID
FROM COURSE C,PIVOT P
) TEMP
      WHERE TEMP.TEACHERID IN(
            SELECT A.ID
            FROM TEACHER A
            WHERE A.SCALE>2 AND A.AGE = 41 AND A.GENDER = 0)


步骤三: 分组统计,课程是由1位以上符合要求老师教的
SELECT TEMP.NAME
FROM(
SELECT C.ID ,C.NAME,
       CASE
       WHEN P.ID = 1 THEN C.TEACHER1
       WHEN P.ID = 2 THEN C.TEACHER2
       WHEN P.ID = 3 THEN C.TEACHER3
       WHEN P.ID = 4 THEN C.TEACHER4
       WHEN P.ID = 5 THEN C.TEACHER5
       ELSE 0
       END
       AS teacherID
FROM COURSE C,PIVOT P
) TEMP
      WHERE TEMP.TEACHERID IN(
            SELECT A.ID
            FROM TEACHER A
            WHERE A.SCALE>2 AND A.AGE < 40 AND A.GENDER = 0)
GROUP BY TEMP.NAME
HAVING COUNT(*) > 1;
    

你可能感兴趣的:(oracle,sql,C++,c,C#)