我在平面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引擎制作的解决方案(日期格式,条件,订购等)
答案 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