切换到Doctrine:如何实现这样的查询?

时间:2017-07-06 19:30:18

标签: php mysql doctrine-orm

我在平面PHP上构建了一个TaskManager,现在我想在Symfony上构建它。

我有这样的查询字符串来填充当天的TasksTable:

 (SELECT id, name, description, time, length
                           FROM daily 
                           WHERE 
                           (day = DAYNAME(:date)
                           OR day = 'all' 
                           OR (DAYNAME(:date) IN ('Sunday','Saturday') AND day = 'weekend' )
                           OR (DAYNAME(:date) NOT IN ('Sunday','Saturday') AND day = 'workday' ))
                           AND time IS NOT NULL)
                           UNION
                           (SELECT id, name, description,
                           DATE_FORMAT(date, '%H:%i') as time, length
                           FROM events
                           WHERE DATE_FORMAT(date, '%Y-%m-%d') = :date)
                           ORDER BY time

如您所见,它可以获取当前工作日(以及工作日/周末)和当天活动的日常任务。 现在我有两个Doctrine实体 - DailyTask和Event,有两个合适的表,我想将这个查询转换为DQL,以获得一个带有DailyTasks和Events作为查询结果的数组。

问题 - 这样的伎俩不起作用:

$em = $this->getDoctrine()->getManager();
        $query = $em->createQuery("(SELECT id, name, description, time, length
                           FROM OrganizerBundle:DailyTask 
                           WHERE 
                           (day = DAYNAME(:date)
                           OR day = 'all' 
                           OR (DAYNAME(:date) IN ('Sunday','Saturday') AND day = 'weekend' )
                           OR (DAYNAME(:date) NOT IN ('Sunday','Saturday') AND day = 'workday' ))
                           AND time IS NOT NULL)
                           UNION
                           (SELECT id, name, description,
                           DATE_FORMAT(date, '%H:%i') as time, length
                           FROM OrganizerBundle:Event
                           WHERE DATE_FORMAT(date, '%Y-%m-%d') = :date)
                           ORDER BY time")->setParameter('date', $day);

据我所知,Doctrine不支持这样的Union(它只显示前导括号'(')的错误,并且看起来它在括号中存在问题(在嵌套的OR条件中等)。

这里最好的解决方案是什么?到目前为止,我没有看到使用Doctrine有任何好处:(它只会让事情变得困难并导致我在PHP上使用一些可以使用MySQL引擎制作的解决方案(日期格式,条件,订购等)

1 个答案:

答案 0 :(得分:0)

最简单的方法是将其移动到子查询中。通过将ORDER BY置于最后)之外,这实际上是您已经在做的事情。

SELECT  -- notice how I simply put the SELECT statement outside
    * -- you're grabbing all of the unioned content.
FROM
(
    -- I cleared away your spare `()` from in here and re-indented for clarity.
    SELECT id, name, description, time, length
    FROM daily 
        WHERE (
                day = DAYNAME(:date)
                OR day = 'all'
                OR (DAYNAME(:date) IN ('Sunday','Saturday') AND day = 'weekend' )
                OR (DAYNAME(:date) NOT IN ('Sunday','Saturday') AND day = 'workday' )
            )
            AND time IS NOT NULL
UNION
    SELECT id, name, description, DATE_FORMAT(date, '%H:%i') as time, length
    FROM events
        WHERE DATE_FORMAT(date, '%Y-%m-%d') = :date
) subqry -- This lets SQL know that all of the above 
         -- needs to be viewed as "one table"
ORDER BY time