【发布时间】:2021-10-25 15:57:36
【问题描述】:
我有Product 和Booking 实体,我正在尝试选择在给定时间段内尚未预订的产品。换句话说,在给定时间段内选择可用的产品。
为了便于理解,请参阅下面的架构。我只想选择具有 #1 或 #5 等预订的产品,因为它可用。如果产品有 #2、#3、#4、#6 之类的预订,请不要选择它,因为它不可用。
每个|--| 代表一个句点,左侧为startAt 字段,右侧为endAt 字段。
Past Futur
|----------------------------------------------------->
Given period
|--------------|
1 . .
|---------| . .
2 . .
|-----+-| .
. 3 .
. |-----| .
. . 4
. |-+-----|
. . 5
. . |---------|
. 6 .
|-----+--------------+-----|
. .
我的猜测是创建这样的查询:
class ProductRepository extends EntityRepository
{
public function getAvailableProducts(\DateTimeInterface $startAt, \DateTimeInterface $endAt): array
{
return $this->createQueryBuilder('p')
->addSelect('b')
->join('p.bookings', 'b')
->andWhere('b.startAt > :endAt OR b.endAt < :startAt')
->setParameter('startAt', $startAt->format('Y-m-d H:i:s'))
->setParameter('endAt', $endAt->format('Y-m-d H:i:s'))
->getQuery()
->getResult()
;
}
}
但是当andWhere()条件在schema中遇到#1或#5时,即使#2、#3、#4或#6存在,数据库(MYSQL 5.6)也会选择这个产品。
我对这个查询有点卡住了,我觉得我走错了路,所以任何帮助都将不胜感激!
【问题讨论】:
-
您的情况看起来不错,see demo。你能分享一个 SQL 小提琴来重现这个问题吗?
-
@nice_dev 你可以看看我的小提琴here
-
@nice_dev 小提琴中的预期输出应该是没有结果,因为有一些预订与给定时间段重叠。但是通过这个查询,它向我展示了产品,因为 #1 和 #5 满足条件。
-
如果我理解正确,结果是正确的。
['2022-01-05','2022-01-15']不与['2021-11-05','2021-11-10']和['2022-02-01','2022-02-15']重叠。因此,它们都被检索了。 -
@nice_dev 这个查询的重点是确定产品是否可供预订。如果在给定期间
['2022-01-05', '2022-01-15']存在预订,则该产品不可用。所以是的,这个查询的结果是正确的,但它不是正确的查询。我正在寻找一个仅输出可用产品的查询,但我在执行此操作时遇到了困难。
标签: php mysql sql doctrine period