You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调整Doctrine查询逻辑实现返回指定日期可用的客房

核心实现逻辑

首先明确时间段重叠的统一判定规则:只要已有预订的开始时间 < 用户查询的离开时间 且 已有预订的离开时间 > 用户查询的开始时间,就说明该预订和用户的入住时段冲突,对应房间不可用。
我们最终要返回的是没有任何冲突预订的房间,包含完全没有预订记录的空房。

修正后的代码方案

方案1:LEFT JOIN写法(更简洁)

public function findByAvailableBookings($start, $leave)
{
    $qb = $this->createQueryBuilder('r')
        ->leftJoin('r.bookings', 'b', 'WITH', 'b.startDate < :leaveDate AND b.leaveDate > :startDate')
        ->where('b.id IS NULL')
        ->setParameter('startDate', $start)
        ->setParameter('leaveDate', $leave);

    return $qb->getQuery()->getResult();
}

说明

通过左连接仅关联和用户查询时段冲突的预订,当连接出来的预订ID为空时,就说明该房间没有冲突预订,属于可用房间,同时会保留完全没有预订记录的空房。


方案2:NOT EXISTS写法(查询效率更高,大表场景更推荐)

public function findByAvailableBookings($start, $leave)
{
    $qb = $this->createQueryBuilder('r');
    
    $qb->where($qb->expr()->notExists(
        $qb->getEntityManager()->createQueryBuilder()
            ->select('b.id')
            ->from('App\Entity\Booking', 'b') // 此处替换为你自己的Booking实体命名空间
            ->where('b.room = r.id')
            ->andWhere('b.startDate < :leaveDate')
            ->andWhere('b.leaveDate > :startDate')
            ->getDQL()
    ))
    ->setParameter('startDate', $start)
    ->setParameter('leaveDate', $leave);

    return $qb->getQuery()->getResult();
}

边界调整提示

如果你的业务规则不允许客人离开/入住日期重合(比如同一天不能有人退房又有人入住),把上述代码中的<、>替换为<=、>=即可。

内容的提问来源于stack exchange,提问作者Jojo l'artichaut

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 02:45:02