Symfony2+Doctrine2中用DATE_ADD聚合查周起止日期报错求助
解决Doctrine QueryBuilder中日期周范围查询的语法错误问题
你遇到的错误核心原因是Doctrine的DQL不支持原生MySQL的INTERVAL(...) DAY语法——DQL有自己的日期函数规范,和原生SQL写法不同。下面给你两种可行的解决方案,优先推荐第一种用DQL内置函数的方式:
方案一:使用Doctrine内置的DATE_ADD函数(推荐)
Doctrine的DATE_ADD函数语法是:DATE_ADD(date, interval, unit),其中unit是字符串类型(比如'DAY'、'MONTH'),而不是原生MySQL的INTERVAL X DAY格式。同时注意修正你代码里的几个小问题:
- 移除
week_number里多余的右括号 - 如果
r.eventDate已经是DateTime类型,不需要用STR_TO_DATE转换,直接使用字段即可
修改后的完整QueryBuilder代码:
$qb = $this->createQueryBuilder('r'); $query = $qb->select([ "COUNT(r.id) as events_amount", "MAX(r.eventDate) AS event_date", "DATE(DATE_ADD(r.eventDate, (1 - DAYOFWEEK(r.eventDate)), 'DAY')) AS start_of_week", "DATE(DATE_ADD(r.eventDate, (7 - DAYOFWEEK(r.eventDate)), 'DAY')) AS end_of_week", "WEEK(r.eventDate) AS week_number" ]) ->where('r.eventDate BETWEEN :start_date AND :end_date') ->groupBy('week_number') ->orderBy('event_date', 'ASC') ->setParameter('start_date', $start_date) // 直接传DateTime对象,Doctrine会自动处理 ->setParameter('end_date', $end_date);
补充说明:
DAYOFWEEK函数在DQL中是支持的,返回值1代表周日,7代表周六(和MySQL一致)- 如果你的
eventDate是字符串类型而非DateTime,那可以保留STR_TO_DATE(r.eventDate, '%Y-%m-%d'),但更建议在实体映射时把字段类型设为datetime,避免额外转换
方案二:使用原生SQL查询(复杂场景可选)
如果需要完全使用原生MySQL语法,可以直接创建原生查询,绕过DQL的语法限制:
$sql = " SELECT COUNT(r.id) as events_amount, MAX(r.eventDate) AS event_date, DATE(DATE_ADD(r.eventDate, INTERVAL(1 - DAYOFWEEK(r.eventDate)) DAY)) as start_of_week, DATE(DATE_ADD(r.eventDate, INTERVAL(7 - DAYOFWEEK(r.eventDate)) DAY)) as end_of_week, WEEK(STR_TO_DATE(r.eventDate, '%Y-%m-%d')) as week_number FROM your_table_name r WHERE STR_TO_DATE(r.eventDate, '%Y-%m-%d') BETWEEN :start_date AND :end_date GROUP BY week_number ORDER BY event_date ASC "; $connection = $this->getEntityManager()->getConnection(); $stmt = $connection->prepare($sql); $stmt->execute([ 'start_date' => $start_date->format('Y-m-d'), 'end_date' => $end_date->format('Y-m-d') ]); $result = $stmt->fetchAllAssociative();
(注意替换your_table_name为你的实体对应的数据库表名)
内容的提问来源于stack exchange,提问作者Volo
相关产品推荐
相关产品推荐

