1. 구분 테이블 t_dept
dept_idx | dept_join | dept_name |
1 | 0 | 야외 스포츠 |
2 | 1 | 축구 |
3 | 1 | 야구 |
4 | 2 | 아시안게임 축구 경기 |
5 | 2 | 월드컵 경기 |
6 | 3 | KBO |
7 | 3 | MLB |
8 | 0 | 실내스포츠 |
9 | 8 | 탁구 |
10 | 8 | 배드민턴 |
11 | 9 | 중국 탁구리그 |
12 | 9 | 한국 탁구리그 |
13 | 9 | 일본 탁구리그 |
2. user 테이블 t_user
user_idx | user_name | dept_idx |
1 | 이승엽 (KBO) | 6 |
2 | 이병규 (KBO) | 6 |
3 | 선동렬 (KBO) | 6 |
4 | Scott Alexander (MLB) | 7 |
5 | 이용대 (배드민턴) | 10 |
6 | 이동수 (배드민턴) | 10 |
3. 장비 테이블 t_equipment
equipment_idx | equipment_name | user_idx |
1 | 엘지트윈스 배트 | 2 |
2 | 선동렬 글러브 | 3 |
3 | 갤럭시 S9 | 5 |
4 | 고급 배드민턴 공 | 6 |
안녕하세요!
위 세 테이블로 아래와 같은 조건의 데이터 select가 가능할까요?
1. 구분 테이블은 각 로우에 종속이 됩니다. dept_idx 컬럼에 상위 구분의 dept_idx가 들어가며, 최상위 구분일 경우 0이 들어갑니다.
2. 구분테이블의 하위 구분 등록은 무한대로 가능합니다.
원하는 출력 내용 : dept_idx를 지정 시 그 구분을 포함한 모든 하위 구분의 유저 수, 장비 수
ex) where dept_idx = 6
result : 유저 : 3 , 장비 : 2
하위구분이 무한으로 가능해서 유동적(루프문 사용 등)으로 쿼리 작성이 필요할 것 같은데 이를 프로시저나 프로그램코딩 말고
쿼리로만 작성이 가능할까요?
서울은 아침까지 흐리더니 해가떠서 덥네요..
모두 장마철 건강 조심하시기 바랍니다.
장비수 1개가 맞다면
WITH T_DEPT AS ( SELECT 1 AS dept_idx, 0 AS dept_join, '야외 스포츠' AS dept_name FROM DUAL UNION ALL SELECT 2, 1, '축구' FROM DUAL UNION ALL SELECT 3, 1, '야구' FROM DUAL UNION ALL SELECT 4, 2, '아시안게임 축구 경기' FROM DUAL UNION ALL SELECT 5, 2, '월드컵 경기' FROM DUAL UNION ALL SELECT 6, 3, 'KBO' FROM DUAL UNION ALL SELECT 7, 3, 'MLB' FROM DUAL UNION ALL SELECT 8, 0, '실내스포츠' FROM DUAL UNION ALL SELECT 9, 8, '탁구' FROM DUAL UNION ALL SELECT 10, 8, '배드민턴' FROM DUAL UNION ALL SELECT 11, 9, '중국 탁구리그' FROM DUAL UNION ALL SELECT 12, 9, '한국 탁구리그' FROM DUAL UNION ALL SELECT 13, 9, '일본 탁구리그' FROM DUAL ), T_USER AS ( SELECT 1 AS user_idx, '이승엽 (KBO)' AS user_name, 6 AS dept_idx FROM DUAL UNION ALL SELECT 2, '이병규 (KBO)', 6 FROM DUAL UNION ALL SELECT 3, '선동렬 (KBO)', 6 FROM DUAL UNION ALL SELECT 4, 'Scott Alexander (MLB)', 7 FROM DUAL UNION ALL SELECT 5, '이용대 (배드민턴)', 10 FROM DUAL UNION ALL SELECT 6, '이동수 (배드민턴)', 10 FROM DUAL ), T_EQUIPMENT AS ( SELECT 1 AS equipment_idx, '엘지트윈스 배트' AS equipment_name, 2 AS user_idx FROM DUAL UNION ALL SELECT 2, '선동렬 글러브', 6 FROM DUAL UNION ALL SELECT 3, '갤럭시 S9', 10 FROM DUAL UNION ALL SELECT 4, '고급 배드민턴 공', 10 FROM DUAL ) SELECT COUNT(*) AS 유저수, MAX((SELECT COUNT(*) FROM T_EQUIPMENT WHERE user_idx = T_USER.user_idx)) AS 장비수 FROM T_USER WHERE dept_idx = 6 ;
장비테이블의 키가 어떻게 되나요?
- 장비ID 만 키인가요? ==> 모든 장비는 한사람만 관리
- 장비ID + 유저ID 가 키인가요? ==> 같은 장비를 여러명이 쓸 수 있음.
WITH t_dept AS ( SELECT 1 dept_idx, 0 dept_join, '야외 스포츠' dept_name FROM dual UNION ALL SELECT 2, 1, '축구' FROM dual UNION ALL SELECT 3, 1, '야구' FROM dual UNION ALL SELECT 4, 2, '아시안게임 축구 경기' FROM dual UNION ALL SELECT 5, 2, '월드컵 경기' FROM dual UNION ALL SELECT 6, 3, 'KBO' FROM dual UNION ALL SELECT 7, 3, 'MLB' FROM dual UNION ALL SELECT 8, 0, '실내스포츠' FROM dual UNION ALL SELECT 9, 8, '탁구' FROM dual UNION ALL SELECT 10, 8, '배드민턴' FROM dual UNION ALL SELECT 11, 9, '중국 탁구리그' FROM dual UNION ALL SELECT 12, 9, '한국 탁구리그' FROM dual UNION ALL SELECT 13, 9, '일본 탁구리그' FROM dual ) , t_user AS ( SELECT 1 user_idx, '이승엽 (KBO)' user_name, 6 dept_idx FROM dual UNION ALL SELECT 2, '이병규 (KBO)' , 6 FROM dual UNION ALL SELECT 3, '선동렬 (KBO)' , 6 FROM dual UNION ALL SELECT 4, 'Scott Alexander (MLB)', 7 FROM dual UNION ALL SELECT 5, '이용대 (배드민턴)' , 10 FROM dual UNION ALL SELECT 6, '이동수 (배드민턴)' , 10 FROM dual ) , t_equipment AS ( SELECT 1 equipment_idx, '엘지트윈스 배트' equipment_name, 2 user_idx FROM dual UNION ALL SELECT 2, '선동렬 글러브' , 6 FROM dual UNION ALL SELECT 3, '갤럭시 S9' , 10 FROM dual UNION ALL SELECT 4, '고급 배드민턴 공', 10 FROM dual ) SELECT COUNT(DISTINCT u.user_idx) user_cnt , COUNT(e.equipment_idx) equipment_cnt -- , COUNT(DISTINCT e.equipment_idx) equipment_cnt FROM (SELECT * FROM t_dept START WITH dept_idx = 6 CONNECT BY PRIOR dept_idx = dept_join ) d , t_user u , t_equipment e WHERE d.dept_idx = u.dept_idx(+) AND u.user_idx = e.user_idx(+) ;
마농님 답변주신 내용 토대로 아래와 같이 고쳐서 완성했습니다. 도움주셔서 감사합니다! SELECT COUNT(DISTINCT u.user_idx) user_cnt , COUNT(i.equipment_idx) equipment_cnt FROM ( select DEPT_IDX, DEPT_NAME, DEPT_JOIN from (select * from T_DEPT order by DEPT_JOIN, DEPT_IDX) products_sorted, (select @pv := '6') initialisation where (find_in_set(DEPT_JOIN, @pv) and length(@pv := concat(@pv, ',', DEPT_IDX))) or dept_idx = 6 ) d left join t_user u on(d.dept_idx = u.DEPT_IDX) left join T_EQUIPMENT i on(u.user_idx = i.USER_IDX)