按日期搜索时 Doctrine 查询找不到记录
Doctrine query failing to find records when searching by date
我们有一个带有 shippingDateTime
的 SalesOrder
实体,我正在将 $startDate
和 $endDate
DateTime
对象传递给查询构建器,如下所示:
/**
* @param \DateTime $startDate
* @param \DateTime|null $endDate
*
* @return array|null
*/
public function getShippedOrdersByDateRange(\DateTime $startDate, ?\DateTime $endDate = null): ?array
{
$builder = $this->createQueryBuilder('o');
$builder->select('o')
->where('o.shippedDateTime >= :startDate')
->andWhere('o.shipped = true')
->andWhere('o.deleted = false')
->setParameter('startDate', $startDate, Type::DATE);
if (!\is_null($endDate)) {
$builder->andWhere('o.shippedDateTime <= :endDate')
->setParameter('endDate', $endDate, Type::DATE);
}
return $builder->getQuery()->getResult();
}
现在有 shippedDateTime
为 2020-05-12
和 2020-05-13
的销售订单,但如果我尝试以下操作,我会得到奇怪的结果:
开始日期:2020-05-12
结束日期:2020-05-12
没有结果,即使查询显示 startDate >=
和 endDate <=
所以我应该在 5 月 12 日有 1 个结果!
开始日期:2020-05-12
结束日期:2020-05-13
给我 1 个结果,发货日期是 5 月 12 日,而不是 2 个结果,一个是 12 日,一个是 13 日!
所以我有点困惑,为什么查询忽略了我要求结束日期更小或等于的事实,所以如果我将 2020-05-12 作为开始日期和结束日期, 查询不应该给我发货日期大于或等于 12 日且小于或等于 12 日的结果,意思是同一天吗??
在数据库中,它们只是存储为标准 mysql datetime
字段,例如 2020-05-12 12:00:00
如果用户只想要一天,则必须将结束日期设置得高 1 天是没有意义的。
您正在传递一个 Type::DATE
参数,但您的数据库中有 DateTime
列。
最后,您的查询将被评估为:
WHERE '2020-05-12 12:00:00' >= '2020-05-12'
AND '2020-05-12 12:00:00' <= '2020-05-12'
通过省略比较值的时间;你得到 00:00:00
次。
谓词的第一部分计算结果为 true
(2020-05-12 12:00:00
是 大于 2020-05-12 00:00:00
),但第二部分在逻辑上失败了( 2020-05-12 12:00:00
不小于2020-05-12 00:00:00
)
(true && false) === false
.
你的另一个例子完全一样。
如果要使用 <=
,则必须为谓词的第二部分传递日期时间 (Type::DateTime
) 值,并为时间指定 23:59:59
部分。
但是直接用<
比较一下你不感兴趣的日期比较简单,也很容易理解。
我们有一个带有 shippingDateTime
的 SalesOrder
实体,我正在将 $startDate
和 $endDate
DateTime
对象传递给查询构建器,如下所示:
/**
* @param \DateTime $startDate
* @param \DateTime|null $endDate
*
* @return array|null
*/
public function getShippedOrdersByDateRange(\DateTime $startDate, ?\DateTime $endDate = null): ?array
{
$builder = $this->createQueryBuilder('o');
$builder->select('o')
->where('o.shippedDateTime >= :startDate')
->andWhere('o.shipped = true')
->andWhere('o.deleted = false')
->setParameter('startDate', $startDate, Type::DATE);
if (!\is_null($endDate)) {
$builder->andWhere('o.shippedDateTime <= :endDate')
->setParameter('endDate', $endDate, Type::DATE);
}
return $builder->getQuery()->getResult();
}
现在有 shippedDateTime
为 2020-05-12
和 2020-05-13
的销售订单,但如果我尝试以下操作,我会得到奇怪的结果:
开始日期:2020-05-12
结束日期:2020-05-12
没有结果,即使查询显示 startDate >=
和 endDate <=
所以我应该在 5 月 12 日有 1 个结果!
开始日期:2020-05-12
结束日期:2020-05-13
给我 1 个结果,发货日期是 5 月 12 日,而不是 2 个结果,一个是 12 日,一个是 13 日!
所以我有点困惑,为什么查询忽略了我要求结束日期更小或等于的事实,所以如果我将 2020-05-12 作为开始日期和结束日期, 查询不应该给我发货日期大于或等于 12 日且小于或等于 12 日的结果,意思是同一天吗??
在数据库中,它们只是存储为标准 mysql datetime
字段,例如 2020-05-12 12:00:00
如果用户只想要一天,则必须将结束日期设置得高 1 天是没有意义的。
您正在传递一个 Type::DATE
参数,但您的数据库中有 DateTime
列。
最后,您的查询将被评估为:
WHERE '2020-05-12 12:00:00' >= '2020-05-12'
AND '2020-05-12 12:00:00' <= '2020-05-12'
通过省略比较值的时间;你得到 00:00:00
次。
谓词的第一部分计算结果为 true
(2020-05-12 12:00:00
是 大于 2020-05-12 00:00:00
),但第二部分在逻辑上失败了( 2020-05-12 12:00:00
不小于2020-05-12 00:00:00
)
(true && false) === false
.
你的另一个例子完全一样。
如果要使用 <=
,则必须为谓词的第二部分传递日期时间 (Type::DateTime
) 值,并为时间指定 23:59:59
部分。
但是直接用<
比较一下你不感兴趣的日期比较简单,也很容易理解。