질문의 주제는 자리 좌석 배정입니다.
이게 SQL로 가능할지요?
조회 테이블은 교실(ROOM), 고객(PERSON) 2개 입니다.
ROOM(교실) | ||
ROOMNO | COL | ROW |
1 | 2 | 4 |
2 | 3 | 4 |
3 | 2 | 6 |
PERSON(고객) | |||
NAME | APPLYNO | SEAT | ROOM |
홍길동1 | 10001 | ||
홍길동2 | 10002 | ||
홍길동3 | 10003 | ||
홍길동4 | 10004 | ||
홍길동5 | 10005 | ||
홍길동6 | 10006 | ||
홍길동7 | 10007 | ||
홍길동8 | 10008 | ||
홍길동9 | 10009 | ||
홍길동10 | 10010 | ||
홍길동11 | 10011 | ||
홍길동12 | 10012 | ||
홍길동13 | 10013 | ||
홍길동14 | 10014 | ||
홍길동15 | 10015 | ||
홍길동16 | 10016 | ||
홍길동17 | 10017 | ||
홍길동18 | 10018 | ||
홍길동19 | 10019 | ||
홍길동20 | 10020 |
1. 교실은 3개가 있구요 고객은 20명입니다. 근데 교실마다 좌석수가 다릅니다.
2. 고객은 교실에 랜덤으로 들어가야 합니다.
3. 단 고객은 교실내에 인원수만큼 균등하게 들어가야 하며, 가령 고객이 20명, 교실이 3개면 한 교실에 6~7명이 들어가야 하는 애깁니다.
4. 고객의 좌석번호도 만들어져야 하며 띄엄 띄엄 앉을 수 없습니다. 좌석번호의 제일 첫좌석은 번호는 1_1 입니다. ( COL + "_" + ROW ) 입니다.
결과는 아래처럼 유사하게 나와야 합니다.
PERSON | |||
NAME | APPLYNO | SEAT | ROOM |
홍길동1 | 10001 | 1_1 | 1 |
홍길동2 | 10002 | 2_1 | 1 |
홍길동3 | 10003 | 1_2 | 1 |
홍길동4 | 10004 | 2_2 | 1 |
홍길동5 | 10005 | 1_3 | 1 |
홍길동6 | 10006 | 2_3 | 1 |
홍길동7 | 10007 | 1_1 | 2 |
홍길동8 | 10008 | 2_1 | 2 |
홍길동9 | 10009 | 3_1 | 2 |
홍길동10 | 10010 | 1_2 | 2 |
홍길동11 | 10011 | 2_2 | 2 |
홍길동12 | 10012 | 3_2 | 2 |
홍길동13 | 10013 | 1_4 | 2 |
홍길동14 | 10014 | 1_1 | 3 |
홍길동15 | 10015 | 2_1 | 3 |
홍길동16 | 10016 | 3_1 | 3 |
홍길동17 | 10017 | 1_2 | 3 |
홍길동18 | 10018 | 2_2 | 3 |
홍길동19 | 10019 | 3_2 | 3 |
홍길동20 | 10020 | 1_4 | 3 |
WITH room AS ( SELECT 1 roomno, 2 col_, 4 row_ FROM dual UNION ALL SELECT 2, 3, 4 FROM dual UNION ALL SELECT 3, 2, 6 FROM dual ) , person AS ( SELECT '홍길동1' name, 10001 applyno FROM dual UNION ALL SELECT '홍길동2' , 10002 FROM dual UNION ALL SELECT '홍길동3' , 10003 FROM dual UNION ALL SELECT '홍길동4' , 10004 FROM dual UNION ALL SELECT '홍길동5' , 10005 FROM dual UNION ALL SELECT '홍길동6' , 10006 FROM dual UNION ALL SELECT '홍길동7' , 10007 FROM dual UNION ALL SELECT '홍길동8' , 10008 FROM dual UNION ALL SELECT '홍길동9' , 10009 FROM dual UNION ALL SELECT '홍길동10', 10010 FROM dual UNION ALL SELECT '홍길동11', 10011 FROM dual UNION ALL SELECT '홍길동12', 10012 FROM dual UNION ALL SELECT '홍길동13', 10013 FROM dual UNION ALL SELECT '홍길동14', 10014 FROM dual UNION ALL SELECT '홍길동15', 10015 FROM dual UNION ALL SELECT '홍길동16', 10016 FROM dual UNION ALL SELECT '홍길동17', 10017 FROM dual UNION ALL SELECT '홍길동18', 10018 FROM dual UNION ALL SELECT '홍길동19', 10019 FROM dual UNION ALL SELECT '홍길동20', 10020 FROM dual ) SELECT x.name , x.applyno , y.roomno , y.seat FROM (SELECT name , applyno , ROW_NUMBER() OVER(ORDER BY applyno) rn -- 응시순서 -- , ROW_NUMBER() OVER(ORDER BY dbms_random.value) rn -- 랜덤순서 FROM person ) x , (SELECT roomno , seat , ROW_NUMBER() OVER(ORDER BY roomno, lv) rn FROM (SELECT a.roomno , b.lv , (MOD(b.lv - 1, a.col_) + 1) ||'_'|| CEIL(b.lv / a.col_) seat , ROW_NUMBER() OVER(ORDER BY b.lv, a.roomno) rn FROM room a , (SELECT LEVEL lv FROM dual CONNECT BY LEVEL <= 99) b WHERE b.lv <= a.col_ * a.row_ ) WHERE rn <= (SELECT COUNT(*) FROM person) ) y WHERE x.rn = y.rn ;