ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Sequelize] 시퀄라이즈로 날짜 필터링 쿼리 구현하기
    programing/Language 2019. 10. 17. 14:41

    안녕하세요, Einere입니다.

    (ADblock을 꺼주시면 감사하겠습니다.)


    이번 포스트에서는 sequelize를 이용하여 날짜 필터링 쿼리를 구현해보도록 하겠습니다.

     

     

    idea

    숙소 예약 시스템을 만들고자 할 때, 체크인 날짜와 체크아웃 날짜를 이용해 예약가능한 숙소를 얻고자 합니다.

    이때, 예약이 불가능한 예약들을 필터링하는 로직은 다음과 같습니다.

    • checkIn <= reservationCheckIn <= checkOut
    • or
    • checkIn <= reservationCheckOut <= checkOut

    여기서 checkIn과 checkOut은 Reservation테이블의 컬럼명이며, reservationCheckIn과 reservationCheckOut은 사용자가 건네주는 예약하고자 하는 날짜입니다. 즉, 사용자가 지정한 날짜에 예약이 이미 되어 있는 예약들을 얻을 수 있습니다.

    이렇게 불가능한 예약들을 얻은 후, NOT IN연산을 통해 예약이 가능한 숙소들을 구합니다.

     

     

    query

    위 아이디어를 쿼리로 나타내면 다음과 같습니다.

    SELECT * FROM Rooms 
    WHERE Rooms.id NOT IN (
    	SELECT id FROM Reservations 
    	WHERE 
    		(checkIn <= reservationCheckIn AND reservationCheckIn <= checkOut) 
    		OR 
    		(checkIn <= reservationCheckOut AND reservationCheckOut <= checkOut)
    );

     

     

    sequelize

    위 SQL을 시퀄라이즈 함수로 변형하면 다음과 같습니다.

    // 사용자가 예약하고자 하는 체크인 날짜와 체크아웃 날짜
    const checkInDate = new Date(checkIn);
    const checkOutDate = new Date(checkOut);
    // 해당 기간에 예약이 되어 있는 예약들을 얻는다
    const rows = await db.Reservation.findAll({
         attributes: ['id'],
         where: {
            [and]: [
                {
                    [or]: [
                         {checkin: {[lte]: checkInDate}},
                         {checkin: {[lte]: checkOutDate}}
                     ]
                },
                {
                    [or]: [
                        {checkOut: {[gte]: checkInDate}},
                        {checkOut: {[gte]: checkOutDate}}
                    ]
                }
            ]
        }
    });
    // 해당 예약들을 제외한 숙소들을 얻는다
    return db.Room.findAll({
        include: [{model: db.Reservation}],
            where: {
                id: {
                    [notIn]: rows.map(row => row.id)
            }
        }
    });

    여기서는 and와 or을 서로 바꿔줬습니다. 로직 자체는 위 쿼리와 동일합니다.

    댓글

Designed by black7375.