Symfony2/Doctrine中如何在WHERE与GROUP BY中使用LENGTH函数?
问题解答
1. 修正筛选条件的代码问题
你的代码首先存在语法错误:select("name, out_number in_number, duration")里的out_number和in_number之间缺少逗号,导致SQL解析失败,这是无法获取数据的直接原因。
另外补充一个细节:如果表中out_number和in_number是数值类型(比如INT),直接用LENGTH()计算长度可能存在隐含问题(数值类型的LENGTH()返回字节数,虽然数字场景下结果一致,但转换为字符串后更严谨);如果是字符串类型则直接用CHAR_LENGTH()即可。
修正后的代码:
$q = $this->_em->getConnection()->createQueryBuilder(); $q->select("name, out_number, in_number, duration") // 补全字段间的逗号 ->from(MAUTIC_TABLE_PREFIX . 'logCall') ->where("CHAR_LENGTH(CAST(in_number AS CHAR)) = 3") ->andWhere("CHAR_LENGTH(CAST(out_number AS CHAR)) = 3") ->orderBy('id', 'DESC'); $result = $q->execute()->fetchAll(); return $result;
如果你的字段本身就是字符串类型,可简化为CHAR_LENGTH(in_number) = 3,无需CAST转换。
2. 同一查询实现双向分组统计
可以用UNION ALL合并两个分组查询,一次执行就能同时得到out_number和in_number的总时长统计,不需要分开查询。
核心思路:
- 第一个子查询:按
out_number分组,统计呼出总时长,标记类型为out - 第二个子查询:按
in_number分组,统计呼入总时长,标记类型为in - 用
UNION ALL合并两个结果集,保留所有数据
代码示例:
// 构建呼出号码统计查询 $qOut = $this->_em->getConnection()->createQueryBuilder(); $qOut->select("out_number AS number, SUM(duration) AS total_duration, 'out' AS type") ->from(MAUTIC_TABLE_PREFIX . 'logCall') ->where("CHAR_LENGTH(CAST(out_number AS CHAR)) = 3") ->groupBy('out_number'); // 构建呼入号码统计查询 $qIn = $this->_em->getConnection()->createQueryBuilder(); $qIn->select("in_number AS number, SUM(duration) AS total_duration, 'in' AS type") ->from(MAUTIC_TABLE_PREFIX . 'logCall') ->where("CHAR_LENGTH(CAST(in_number AS CHAR)) = 3") ->groupBy('in_number'); // 合并两个查询并执行 $unionSql = $qOut->getSQL() . ' UNION ALL ' . $qIn->getSQL(); $result = $this->_em->getConnection()->executeQuery($unionSql)->fetchAll(); return $result;
执行后会得到类似如下结构的结果,清晰区分每个号码的呼出/呼入总时长:
array( ['number' => '302', 'total_duration' => 70, 'type' => 'out'], ['number' => '303', 'total_duration' => 20, 'type' => 'out'], ['number' => '111', 'total_duration' => 10, 'type' => 'out'], ['number' => '400', 'total_duration' => 60, 'type' => 'in'], ['number' => '401', 'total_duration' => 20, 'type' => 'in'], ['number' => '302', 'total_duration' => 10, 'type' => 'in'], )
内容的提问来源于stack exchange,提问作者Miedkes
相关产品推荐
相关产品推荐

