如何在Doctrine 2中按日期时间排序?

6

我想执行以下查询:

        $qb = $this->getEntityManager()->createQueryBuilder();

        $qb->select( 'e' )
            ->from( 'Entity\Event',  'e' )
            ->setMaxResults( $limit )
            ->setFirstResult( $offset )
            ->orderBy('e.dateStart', 'ASC');

        $events = $qb->getQuery()->getResult();

Where

/**
 * User
 *
 * @ORM\Table(name="event")
 * @ORM\Entity(repositoryClass="Repositories\EventRepository")
 */
class Event
{
    /**
     * @var \DateTime
     *
     * @ORM\Column(name="date_start", type="datetime", precision=0, scale=0, nullable=true, unique=false)
     */
    private $dateStart;

...
}

但是按顺序排序不起作用。 我的结果没有按开始日期显示。
我想检索从最近到最新的前20个事件。
我该怎么做?
谢谢
编辑:
根据之前的答案,我更新了我的查询。 不幸的是,我仍然不能让它工作。 请帮忙。
     $qb->select( 'e' )
        ->from( 'Entity\Event',  'e' )
        ->Where( 
            $qb->expr()->andX(
                $qb->expr()->between('e.dateStart', ':from', ':to')
            )
        )
        ->orderBy('e.dateStart', 'ASC')
        ->setFirstResult( $offset )
        ->setMaxResults( $limit );

谢谢

编辑2: 移动orderBy似乎确实有所不同。目前为止,我没有任何错误。脚本使用orderBy运行良好,但根本没有按照日期时间排序!

在我的结果中,我看不到任何让我认为它是基于任何给定属性排序的东西,绝对不是日期时间!

这怎么可能?

Datetime字段在数据库中看起来像这样: 2014-05-24 19:30:00

当我var Dump之前的查询时,这是我对datetie字段的理解:

 ["dateStart"]=> string(8) "DateTime"

这是否意味着对于教条来说,它实际上是一个字符串,因此不按日期时间排序?

谢谢


2
精度=0,比例=0,当字段类型为日期时间时是否需要?奇怪...将这两个删除,因为它们是针对数字类型的,然后尝试一下...如果我错了,请纠正我。 - gkd
你说得对,它只适用于十进制 :) - Miles M.
我还是无法让它正常工作 :( 有关于此的任何帮助吗? - Miles M.
1
这是确切的查询吗?如果是:您不需要andX(),因为您只有一个表达式。如果不是,请向我们展示确切的查询。我们需要知道是否有JOIN子句,或者您是否正在使用Doctrine Paginator等等... - Jasper N. Brouwer
Doctrine完全可以通过日期时间属性对结果进行排序。如果顺序出错,那么你肯定做了一些你没有告诉我们的事情... - Jasper N. Brouwer
显示剩余7条评论
5个回答

11

数据库

您应该在数据库中检查表格结构:

date_start列的类型是什么?
它应该是 DATETIME(在MySQL中,其他供应商可能会有所不同)
但我怀疑它是某种形式的字符串,如 VARCHAR(或 CHARTEXT等)。

当出现这种情况时,结果是有序的,但不是您期望的方式。这是因为不同类型的数据库按不同的方式排序。

命令行工具

Doctrine带有一个控制台工具,可以验证您的映射并检查数据库是否与其一致:doctrine orm:validate-schema

如果它报告数据库不一致,请使用doctrine orm:schema-tool:update --dump-sql让它显示要执行的查询以更新数据库(它将假定映射是真实性的来源)。


谢谢Jasper。这是我对该字段的注释。它是DATETIME类型。 /** * @var \DateTime * * @ORM\Column(name="date_start", type="datetime", nullable=true, unique=false) */ private $dateStart; - Miles M.
1
@Miles M. 我说的不是映射元数据(注释),而是实际的数据库。(Doctrine 不执行查询,因此无法对结果进行排序,它只生成查询。执行查询的是 _数据库_。) - Jasper N. Brouwer

6

您的查询应该像这样:

    $qb->select( 'e' )
        ->from( 'Entity\Event',  'e' )
        ->orderBy('e.dateStart', 'ASC');
        ->setFirstResult( $offset )
        ->setMaxResults(20);

你需要尊重查询构建器参数的顺序,希望这可以帮助你。


我不知道有一个特定的顺序,我在哪里可以学习正确的顺序?我已经多次阅读了D2文档,但从未看到过这个。 - Miles M.
经过多次测试,实际上这并没有起作用。 我已更新我的答案,粘贴了我的实际查询。 - Miles M.
这篇文章对你很有用。请查看13.2.5点。Expr。 - gkd
你在说哪些参数,@TahaMetal?方法调用的顺序在这里并不重要。 - Florian Klein

1
也许你可以像这样重写你的代码:

Maybe you can rewrite your code like this

 $qb = $this->getEntityManager()->createQueryBuilder();

    $qb->select( 'e' )
        ->from( 'Entity\Event',  'e' )
        ->setMaxResults( $limit )
        ->setFirstResult( $offset )
        ->orderBy('date(e.dateStart) ASC');//this is the trick that works for me

    $events = $qb->getQuery()->getResult();

对我来说失败了:我得到了[Syntax Error] line 0, col 191: Error: Expected known function, got 'date'(Doctrine 2.8.x)。 - k00ni

1

你能给我以下代码的结果吗:

$qb->select( 'e' )
    ->from( 'Entity\Event',  'e' )
    ->setMaxResults( $limit )
    ->setFirstResult( $offset )
    ->orderBy('e.dateStart', 'ASC');

die($qb->getQuery()->getSql());

一个可能的想法: 你的属性 $dateStart 的 getter 是否声明正确?应该是这样的:
public function getDateStart()
{
    return $this->dateStart;
}

getter与DQL无关。 - Florian Klein
哪些getter方法? 这是当我输出SQL时发生的情况:SELECT e0_.id AS id0, e0_.name AS name1, e0_.description AS description2, e0_.link AS link3, e0_.social_media_link AS social_media_link4, e0_.booking_link AS booking_link5, e0_.price AS price6, e0_.currency AS currency7, e0_.picture AS picture8, e0_.date_created AS date_created9, e0_.date_start AS date_start10, e0_.date_end AS date_end11, e0_.popularity AS popularity12, e0_.confirmed AS confirmed13, e0_.user_id AS user_id14, e0_.admin_id AS admin_id15, e0_.place_id AS place_id16 FROM event e0_ ORDER BY e0_.date_start ASC LIMIT 200 OFFSET 0 - Miles M.
使用您建议的简化查询。 - Miles M.

0

查询参数的顺序很重要。在您的情况下,查询应该是:

    $events = $qb->select( 'e' )
        ->from( 'Entity\Event',  'e' )
        ->orderBy('e.dateStart', 'DESC')
        ->setFirstResult( $offset )
        ->setMaxResults( $limit )
        ->getQuery()
        ->getResult();

我不太确定你所说的“从最早到最近发生的前20个事件”,但这应该会给你最新的一组事件。要更改顺序,请将“DESC”更改为“ASC”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接