create table tblcourse(pid number,course varchar2(20));
Insert into TBLCOURSE (PID, COURSE) Values (1, 'COURSE1');
Insert into TBLCOURSE (PID, COURSE) Values (1, 'COURSE3');
Insert into TBLCOURSE (PID, COURSE) Values (1, 'COURSE5');
Insert into TBLCOURSE (PID, COURSE) Values (2, 'COURSE8');
Insert into TBLCOURSE (PID, COURSE) Values (3, 'COURSE8');
Insert into TBLCOURSE (PID, COURSE) Values (4, 'COURSE2');
Insert into TBLCOURSE (PID, COURSE) Values (5, 'COURSE4');
Insert into TBLCOURSE (PID, COURSE) Values (5, 'COURSE6');
COMMIT;
询问 :
WITH TAB AS
(
SELECT DISTINCT(COURSE) as course
FROM tblcourse --distinct courses
MINUS
SELECT DISTINCT(COURSE) as course
FROM tblcourse
WHERE pid=:pid --will give you distinct courses that pid subscribe
)
SELECT :pid,LISTAGG(COURSE, ',') WITHIN GROUP (ORDER BY COURSE) as courses
FROM TAB;
结果如你所愿: pass pid as 1
PID COURSES
-------------------------
1 COURSE2,COURSE4,COURSE6,COURSE8
SQLFIDDLE 中的试用示例
编辑
我想不出更好的解决方案,可能有人可以提出更好的方法来做到这一点,同时你可以看看这个,但有时笛卡尔积会摇摆不定:)
WITH course_cartesian as (
SELECT pid,course
FROM (SELECT DISTINCT course
FROM tblcourse)q1,
(SELECT DISTINCT pid
FROM tblcourse)q2
ORDER BY pid,course
)
,tbl_course AS(SELECT pid,course
FROM course_cartesian
MINUS
SELECT pid,course FROM tblcourse
)
SELECT pid,listagg(course,',') WITHIN GROUP (ORDER BY course) as courses
FROM tbl_course
GROUP BY pid
ORDER BY pid;
输出
SQLFIDDLE链接