자리 좌석 배정에 관한 쿼리 작성질문 0 2 1,540

by 허승호 [Oracle 기초] 좌석배정 [2019.04.16 15:41:03]


질문의 주제는 자리 좌석 배정입니다.

이게 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
by 마농 [2019.04.16 16:43:18]
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
;

 


by 허승호 [2019.04.17 11:05:21]

감사합니다. 복잡하게 생각했는데 의외로 간단히 푸시니..... 아직 마농님 수준에 미치지 못했나 봅니다. 존경합니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입