강좌정보테이블(TB_CLASS)와 각 강좌마다 등록된 회원테이블(TB_CLASS_USER)이 있습니다
강좌정보를 등록시 해당 강좌에 등록한 학생정보를 함께 입력하고
강좌정보(TB_CLASS)와 함께 강좌정보(SEQ)를 FK로 하여 학생정보(TB_CLASS_USER)들이 등록됩니다
즉 한명의 학생이 여러 강좌정보에 들어가 있을 수 있습니다 (동일한지는 USER_CI 컬럼으로 체크할수 있습니다)
TB_CLASS에는 SEQ, TITLE이 있고
TB_CLASS_USER에는 CLASS_SEQ(FK), SEQ, USER_NAME, USER_AGE, USER_SEQ, USER_CI(사용자 식별값) 등 이 있습니다
(위의 회색으로 된 컬럼명은 null값도 있습니다 )
이때 3개 이상 강좌에 참여하는 학생을 아래와 같이 출력하고싶습니다
학생명 | 참여하는 강좌명 | 개인식별값 |
김수지 | 수학,과학,영어 | fajd09123adfkjlasdf123123 |
김수현 | 영어 | dfajlk123sdfadfdafdf123541 |
아래와 같이 쿼리문을 짯는데 이게 맞을까요?
종류는 오라클입니다
SELECT NVL(MAX(A.NAME),' ') NAME, WM_CONCAT(B.TITLE) AS CLASS_LIST, USER_CI
FROM TB_CLASS_USER A, TB_CLASS B
WHERE 1 = 1
AND A.CLASS_SEQ = B.SEQ
GROUP BY A.USER_CI
HAVING COUNT(DISTINCT A.CLASS_SEQ) > 2
또한 만약 개인식별값(USER_CI)가 null인 사람이 여러명이면 이 또한 어떻게 처리 해야할까요?
성능을 고려하지 않고 만들었습니다.
create table tb_class ( seq number, title varchar2(10) ); create table tb_class_user ( seq number, user_name varchar2(10), user_ci varchar2(10), class_seq number ); delete from tb_class; insert into tb_class values (1, 'korean'); insert into tb_class values (2, 'english'); insert into tb_class values (3, 'mathematic'); select * from tb_class; delete from tb_class_user; insert into tb_class_user values (1, 'aa', '1111', 1); insert into tb_class_user values (2, 'bb', null, 1); insert into tb_class_user values (3, 'cc', '3333', 1); insert into tb_class_user values (4, null, '1111', 2); insert into tb_class_user values (5, 'bb', '2222', 2); insert into tb_class_user values (6, 'cc', '3333', 2); insert into tb_class_user values (7, 'dd', '1111', 3); insert into tb_class_user values (8, 'cc', null, 3); select * from tb_class_user; select a.user_name, a.user_ci, b.title, count(1) over(partition by a.user_ci) cnt from tb_class_user a , tb_class b where a.class_seq = b.seq and a.user_ci is not null ; -- 원하는 결과 select nvl(max(user_name), '') user_name, listagg(title, ',') within group(order by title) title, user_ci from ( select a.user_name, a.user_ci, b.title, count(1) over(partition by a.user_ci) cnt from tb_class_user a , tb_class b where a.class_seq = b.seq and a.user_ci is not null ) where cnt > 2 group by user_ci;
user_ci 가 null 인 자료가 들어오는게 가능한 건가요?
- 업무 로직 검토 필요합니다.
- 가능하다면 왜 그런지 상세 설명이 필요합니다.
Group By 에 a.name 을 추가하면 MAX 필요 없습니다.
NVL 은 굳이 필요 없을 듯 하구요.
Distinct 가 필요한지도 검토 필요합니다.
wm_concat 는 비공식 함수입니다. 11G 라면 ListAgg 이용하세요.
SELECT a.user_ci , a.name , WM_CONCAT(b.title) class_list_10g , LISTAGG(b.title, ',') WITHIN GROUP(ORDER BY b.seq) class_list_11g FROM tb_class_user a , tb_class b WHERE a.class_seq = b.seq GROUP BY a.user_ci, a.name --HAVING COUNT(DISTINCT a.class_seq) > 2 --HAVING COUNT(a.class_seq) > 2 HAVING COUNT(*) > 2 ;