功能:
1、显示某个课时的上课时间和地点
SELECT '第'||A.FPERIODWEEK||'周,星期'|| DECODE(A.FPERIODDAY, 1, '一',
2, '二',
3, '三',
4, '四',
5, '五',
6, '六',
7, '天'
) || '第'||A.FSTARTTIME||','||
A.FENDTIME||'节' COURSETIME,
A.FPERIODPLACENAME COURSEPLACE FROM SJ_CD_PERIODS A WHERE A.FPERIODID
= '20112012141202260210001003001002002';
2、显示所有课时的上课时间和地点
SELECT '第'||A.FPERIODWEEK||'周,星期'|| DECODE(A.FPERIODDAY, 1, '一',
2, '二',
3, '三',
4, '四',
5, '五',
6, '六',
7, '天'
) || '第'||A.FSTARTTIME||','||
A.FENDTIME||'节' COURSETIME,
A.FPERIODPLACENAME COURSEPLACE FROM SJ_CD_PERIODS A;
3、显示某个批次的上课时间和地点(因为一个批次可能有多个课时)
感觉这个还挺难的
1)首先对SJ_CD_PERIODS表中FBATCHSID进行ROW_NUMBER()FPERIODID进行排位并打上排位号;(显示批次号,批次名称(课时表中不存在),课时编号,课时名称,上课时间,上课地点)
SELECT A.FBATCHSID, A.FPERIODID, A.FPERIODNAME, '第'||A.FPERIODWEEK||'周,星期'|| DECODE(A.FPERIODDAY, 1, '一',
2, '二',
3, '三',
4, '四',
5, '五',
6, '六',
7, '天'
) || '第'||A.FSTARTTIME||','||
A.FENDTIME||'节' COURSETIME,
A.FPERIODPLACENAME COURSEPLACE, ROW_NUMBER()
OVER(PARTITION BY A.FBATCHSID ORDER BY A.FBATCHSID, A.FPERIODID) RANK
FROM SJ_CD_PERIODS A ORDER BY A.FBATCHSID, A.FPERIODID;
结果:可以看出,经过ROW_NUMBER()后,课时信息已经按照批次编号进行了排序,并打上了一个位置字段rank;
2)利用oracle的递归查询connect by进行表内递归,并通过sys_connect_by_path进行复制数据追溯串的构造。
这里我们将上面的显示课时信息中的上课时间和地点和并在一个字段中,变成COURSEINFOR,针对这个字段进行构造,使之合并在一个字段内:
SELECT A.FPERIODPLACENAME||',第'||A.FPERIODWEEK||'周,星期'|| DECODE(A.FPERIODDAY, 1, '一',
2, '二',
3, '三',
4, '四',
5, '五',
6, '六',
7, '天'
) || '第'||A.FSTARTTIME||','||
A.FENDTIME||'节' COURSEINFOR FROM SJ_CD_PERIODS A;
上述查询语句就是查询课时表所有课时的上课信息;
将第一步中的对课时表按批次编号进行排序的语句改为:
SELECT A.FBATCHSID, A.FPERIODID, A.FPERIODNAME, A.FPERIODPLACENAME||',第'||A.FPERIODWEEK||'周,星期'|| DECODE(A.FPERIODDAY, 1, '一',
2, '二',
3, '三',
4, '四',
5, '五',
6, '六',
7, '天'
) || '第'||A.FSTARTTIME||','||
A.FENDTIME||'节' COURSEINFOR, ROW_NUMBER()
OVER(PARTITION BY A.FBATCHSID ORDER BY A.FBATCHSID, A.FPERIODID) RANK
FROM SJ_CD_PERIODS A ORDER BY A.FBATCHSID, A.FPERIODID;
接下来就是正题了:
SELECT B.FBATCHSID, B.FPERIODID, B.FPERIODNAME, B.COURSEINFOR, B.RANK, LEVEL AS CURR_LEVEL, LTRIM(SYS_CONNECT_BY_PATH(B.COURSEINFOR, '<br />'),'<br />') COURSEINFOR_PATH FROM
(SELECT A.FBATCHSID, A.FPERIODID, A.FPERIODNAME, A.FPERIODPLACENAME||',第'||A.FPERIODWEEK||'周,星期'|| DECODE(A.FPERIODDAY, 1, '一',
2, '二',
3, '三',
4, '四',
5, '五',
6, '六',
7, '天'
) || '第'||A.FSTARTTIME||','||
A.FENDTIME||'节' COURSEINFOR, ROW_NUMBER()
OVER(PARTITION BY A.FBATCHSID ORDER BY A.FBATCHSID, A.FPERIODID) RANK
FROM SJ_CD_PERIODS A ORDER BY A.FBATCHSID, A.FPERIODID) B CONNECT BY B.FBATCHSID = PRIOR B.FBATCHSID AND B.RANK-1 = PRIOR RANK;
这里我们应该发现一些线索,及对每一批次,CURR_LEVEL最高的那行,有我们所要的数据。那后面该怎么办,取出那个数据?对了,继续用ROW_NUMBER()进行排位标记,然后再按排位标记取出即可。
3)CURR_LEVEL最高的那一行,有我们所要的数据,我们用ROW_NUMBER()对FBATCHSID进行排位标记,然后在按排位标记取出即可
SELECT C.FBATCHSID, C.FPERIODID, C.FPERIODNAME, C.COURSEINFOR, C.RANK, C.CURR_LEVEL, C.COURSEINFOR_PATH, ROW_NUMBER() OVER(PARTITION BY C.FBATCHSID ORDER BY C.FBATCHSID, CURR_LEVEL DESC) COURSEINFOR_PATH_RANK
FROM
(SELECT B.FBATCHSID, B.FPERIODID, B.FPERIODNAME, B.COURSEINFOR, B.RANK, LEVEL AS CURR_LEVEL, LTRIM(SYS_CONNECT_BY_PATH(B.COURSEINFOR, '<br />'),'<br />') COURSEINFOR_PATH FROM
(SELECT A.FBATCHSID, A.FPERIODID, A.FPERIODNAME, A.FPERIODPLACENAME||',第'||A.FPERIODWEEK||'周,星期'|| DECODE(A.FPERIODDAY, 1, '一',
2, '二',
3, '三',
4, '四',
5, '五',
6, '六',
7, '天'
) || '第'||A.FSTARTTIME||','||
A.FENDTIME||'节' COURSEINFOR, ROW_NUMBER()
OVER(PARTITION BY A.FBATCHSID ORDER BY A.FBATCHSID, A.FPERIODID) RANK
FROM SJ_CD_PERIODS A ORDER BY A.FBATCHSID, A.FPERIODID) B CONNECT BY B.FBATCHSID = PRIOR B.FBATCHSID AND B.RANK-1 = PRIOR RANK) C
至此应该很明白了,再进行一次查询,取COURSEINFOR_PATH_RANK为1的即可获得我们想要的结果。
4)获取想要的排位数据,即得到了批次下所有课时多行到单行的合并
SELECT D.FBATCHSID, D.FPERIODID, D.FPERIODNAME, D.COURSEINFOR_PATH
FROM
(SELECT C.FBATCHSID, C.FPERIODID, C.FPERIODNAME, C.COURSEINFOR, C.RANK, C.CURR_LEVEL, C.COURSEINFOR_PATH, ROW_NUMBER() OVER(PARTITION BY C.FBATCHSID ORDER BY C.FBATCHSID, CURR_LEVEL DESC) COURSEINFOR_PATH_RANK
FROM
(SELECT B.FBATCHSID, B.FPERIODID, B.FPERIODNAME, B.COURSEINFOR, B.RANK, LEVEL AS CURR_LEVEL, LTRIM(SYS_CONNECT_BY_PATH(B.COURSEINFOR, '<br />'),'<br />') COURSEINFOR_PATH FROM
(SELECT A.FBATCHSID, A.FPERIODID, A.FPERIODNAME, A.FPERIODPLACENAME||',第'||A.FPERIODWEEK||'周,星期'|| DECODE(A.FPERIODDAY, 1, '一',
2, '二',
3, '三',
4, '四',
5, '五',
6, '六',
7, '天'
) || '第'||A.FSTARTTIME||','||
A.FENDTIME||'节' COURSEINFOR, ROW_NUMBER()
OVER(PARTITION BY A.FBATCHSID ORDER BY A.FBATCHSID, A.FPERIODID) RANK
FROM SJ_CD_PERIODS A ORDER BY A.FBATCHSID, A.FPERIODID) B CONNECT BY B.FBATCHSID = PRIOR B.FBATCHSID AND B.RANK-1 = PRIOR RANK) C)D
WHERE D.COURSEINFOR_PATH_RANK = 1;