使用 Native SQL 的 Doctrine Orm 2 递归查询
Doctrine Orm 2 Recursive query with Native SQL
我正在使用 symfony 框架,它使用 Doctrine Orm 2 和 DQL 与数据库对话。但是,DQL 不支持递归查询。它确实为您提供了使用本机 SQL 以及结果集映射来创建 DQL 不支持的高级查询的选项。
现在开始手头的任务。我正在尝试编写一个函数,当给定一个组 ID 时,我想 return 组的父 ID 和父的父 ID 的数组,直到我们到达父 ID 等于 NULL 的根组。例如,将 3 传递给函数将 return {3,2,1},传递 2 将 return {2,1},传递 1 将 return {1}。
我有一个组 table 这样的
| Group Id | Parent Id |
| 1 | NULL |
| 2 | 1 |
| 3 | 2 |
我目前对这个问题的解决方案只是 return 获取组 ID 的父级并一次又一次地查询数据库,直到找到根组。但是,如果我可以在一个查询中完成这一切,那么 server/DB 需要处理的开销就会少很多。我也不是很熟悉递归查询,但我会随着我对递归查询的更多了解来更新此 post。
更新 1:这是我到目前为止的代码,我还必须更新到 maria db 10.2,因为那是实现递归 cte 支持的时候。我目前正在处理 where 子句中的语法错误。
public function getGroupOwnershipChain($group_id){
$rsm = new ResultSetMapping();
$rsm->addEntityResult('Bundle:Group', 'u');
$rsm->addFieldResult('u', 'id', 'id');
$rsm->addFieldResult('u', 'parent', 'parent');
$query = $this->em->createNativeQuery('
with recursive cte as (
SELECT u.id, u.parent
WHERE u.id = ?
FROM group
UNION ALL
SELECT e.id, e.parent
FROM cte c
JOIN group e ON e.id = c.parent
)
SELECT *
FROM cte;', $rsm);
$query->setParameter(1, $group_id);
return $query->getResult();
}
public function getGroupOwnershipChain($group_id){
$rsm = new ResultSetMapping();
$rsm->addEntityResult('Bundle:Group', 'u');
$rsm->addFieldResult('u', 'id', 'id');
$rsm->addFieldResult('u', 'parent', 'parent');
$query = $this->em->createNativeQuery('
with recursive cte as (
SELECT u.id, u.parent
WHERE u.id = ?
FROM group
UNION ALL
SELECT e.id, e.parent
FROM cte c
JOIN group e ON e.id = c.parent
)
SELECT *
FROM cte;', $rsm);
$query->setParameter(1, $group_id);
return $query->getResult();
}
我不得不在递归锚点中翻转 from 和 where 子句。现在可以正常使用了。
我正在使用 symfony 框架,它使用 Doctrine Orm 2 和 DQL 与数据库对话。但是,DQL 不支持递归查询。它确实为您提供了使用本机 SQL 以及结果集映射来创建 DQL 不支持的高级查询的选项。
现在开始手头的任务。我正在尝试编写一个函数,当给定一个组 ID 时,我想 return 组的父 ID 和父的父 ID 的数组,直到我们到达父 ID 等于 NULL 的根组。例如,将 3 传递给函数将 return {3,2,1},传递 2 将 return {2,1},传递 1 将 return {1}。
我有一个组 table 这样的
| Group Id | Parent Id |
| 1 | NULL |
| 2 | 1 |
| 3 | 2 |
我目前对这个问题的解决方案只是 return 获取组 ID 的父级并一次又一次地查询数据库,直到找到根组。但是,如果我可以在一个查询中完成这一切,那么 server/DB 需要处理的开销就会少很多。我也不是很熟悉递归查询,但我会随着我对递归查询的更多了解来更新此 post。
更新 1:这是我到目前为止的代码,我还必须更新到 maria db 10.2,因为那是实现递归 cte 支持的时候。我目前正在处理 where 子句中的语法错误。
public function getGroupOwnershipChain($group_id){
$rsm = new ResultSetMapping();
$rsm->addEntityResult('Bundle:Group', 'u');
$rsm->addFieldResult('u', 'id', 'id');
$rsm->addFieldResult('u', 'parent', 'parent');
$query = $this->em->createNativeQuery('
with recursive cte as (
SELECT u.id, u.parent
WHERE u.id = ?
FROM group
UNION ALL
SELECT e.id, e.parent
FROM cte c
JOIN group e ON e.id = c.parent
)
SELECT *
FROM cte;', $rsm);
$query->setParameter(1, $group_id);
return $query->getResult();
}
public function getGroupOwnershipChain($group_id){
$rsm = new ResultSetMapping();
$rsm->addEntityResult('Bundle:Group', 'u');
$rsm->addFieldResult('u', 'id', 'id');
$rsm->addFieldResult('u', 'parent', 'parent');
$query = $this->em->createNativeQuery('
with recursive cte as (
SELECT u.id, u.parent
WHERE u.id = ?
FROM group
UNION ALL
SELECT e.id, e.parent
FROM cte c
JOIN group e ON e.id = c.parent
)
SELECT *
FROM cte;', $rsm);
$query->setParameter(1, $group_id);
return $query->getResult();
}
我不得不在递归锚点中翻转 from 和 where 子句。现在可以正常使用了。