在学说中只加入一行

时间:2017-08-22 07:40:07

标签: php symfony doctrine-orm greatest-n-per-group dql

我有一个事件表,其中包含事件的标题和描述,并且我有一个eventInstance表,其中存储了事件的日期和地点。所以它是一对一的关系:一个事件可以有很多实例。

我现在尝试的是仅为事件选择最新的事件实例。在SQL中,查询是:

select e.id, e.title, ei.start_date 
from event e 
LEFT join event_instance ei on ei.id = 
(SELECT id FROM event_instance ei where ei.event_id = e.id ORDER BY start_date asc, start_time asc LIMIT 1) 
ORDER BY start_date asc, start_time asc LIMIT 20;

我试图在dql中重写sql命令。到目前为止,我已经得到了这个:

SELECT e, ei 
FROM AppBundle:Event e LEFT JOIN e.eventInstances ei WITH ei = 
(SELECT a FROM AppBundle:EventInstance a WHERE a.event = e ORDER BY a.startDate asc, a.startTime asc)

我的问题是,dql中没有LIMIT命令,所以我不能限制子查询给我一个结果。因此,执行此查询时得到的错误是:

SQLSTATE[21000]: Cardinality violation: 7 ERROR: more than one row returned by a subquery used as an expression

有什么方法可以让我的工作吗?

2 个答案:

答案 0 :(得分:0)

创建子查询,然后在其上设置最大结果。

$subDql = 'SELECT a
           FROM AppBundle:EventInstance a 
           WHERE a.event = e
           ORDER BY a.startDate asc, a.startTime asc';

$subQuery = $this->getEntityManager()
                 ->createQuery($subDql)
                 ->setMaxResults(1)
;

$dql = 'SELECT e, ei FROM AppBundle:Event e
        LEFT JOIN e.eventInstances ei 
        WITH ei = (' .$subQuery . ')'
;

$query = $this->getEntityManager()
              ->createQuery($dql)
              ->setMaxResults($yourOtherLimit)
;

$resultCollection = $query->getResult();

答案 1 :(得分:0)

您的解决方案(to get latest row per group)的等效DQL将类似于

SELECT e,a 
FROM AppBundle:Event e
    JOIN e.eventInstances a
    LEFT JOIN AppBundle\Entity\Score b 
    WITH a.event = b.event 
    AND a.startDate < b.startDate
    AND a.startTime < b.startTime
WHERE b.event IS NULL
ORDER BY a.startTime DESC

OR

SELECT e,a 
FROM AppBundle:Event e
    JOIN e.eventInstances a
    LEFT JOIN AppBundle\Entity\Score b 
    WITH a.event = b.event 
    AND a.startDate = b.startDate
    AND a.startTime < b.startTime
WHERE b.event IS NULL
ORDER BY a.startTime DESC