交叉连接到 DQL
Cross Join to DQL
我正在尝试将这个我认为简单的 mysql 查询转换为 Doctrine dql,但是,我现在遇到了很大的困难...
SELECT (c.prix-aggregates.AVG) AS test
FROM immobilier_ad_blank c
CROSS JOIN (
SELECT AVG(prix) AS AVG
FROM immobilier_ad_blank)
AS aggregates
这样做的目的:创建 z 分数。
来自这个问题的原始实现 Calculating Z-Score for each row in MySQL? (simple)
我考虑过在实体内创建关联,但我的意思是它没有必要,它仅用于统计。
编辑:顺便说一句,我不想使用原始 SQL,我将使用 getDQL
从另一个查询构建器表达式中提取 "subquery"。否则,我将不得不重写我的动态查询构建器以考虑 rawSQL。
编辑 2:
试过这个
$subQb = $this->_em->createQueryBuilder();
$subQb->addSelect("AVG(subC.prix) as AMEAN")
->from("MomoaIntegrationBundle:sources\Common", "subC");
$subDql = $subQb->getDQL();
$dql = "SELECT c.prix FROM MomoaIntegrationBundle:sources\Common c INNER JOIN ($subDql) AS aggregates";
原始 dql 是:
SELECT c.prix FROM MomoaIntegrationBundle:sources\Common c INNER JOIN (SELECT AVG(subC.prix) as AMEAN FROM MomoaIntegrationBundle:sources\Common subC) AS aggregates
出现这个奇怪的错误:line 0, col 70 near '(SELECT AVG(subC.prix)': Error: Class '(' is not defined.
编辑 3:
我发现有点强硬的方式让它发挥作用,但学说对实体的实施很顽固,忘记了统计不需要实体!
$subQb = $this->_em->createQueryBuilder();
$subQb->addSelect("AVG(subC.prix) as AMEAN")
->from("MomoaIntegrationBundle:sources\Common", "subC");
$sql = "SELECT (c.prix-aggregates.sclr_0) AS test FROM immobilier_ad_blank c CROSS JOIN "
. "({$subQb->getQuery()->getSQL()}) AS aggregates";
$stm = $stm = $this->_em->getConnection()->prepare($sql);
$stm->execute();
$data = $stm->fetchAll();
如果您有更好的解决方案,我洗耳恭听!我实际上不喜欢这个解决方案。
对于复杂的查询,您可能需要考虑绕过 DQL 并使用本机查询 - 特别是因为您不需要实体中的结果。
$connection = $em->getConnection();
$statement = $connection->prepare("
select c.prix-aggregates, t1.avg
from immobilier_ad_blank
cross join (
select avg(prix) as avg
from immobilier_ad_blank
) t1
");
$statement->execute();
$results = $statement->fetchAll();
从 Doctrine 2.4 开始,可以在不使用已定义关联的情况下加入,例如:
SELECT u FROM User u JOIN Items i WITH u.age = i.price
这个没有任何意义,但你明白了。在这种情况下 WITH
关键字是绝对必需的,否则会出现语法错误,但您可以只提供一个虚拟条件,如下所示:
SELECT u FROM User u JOIN Items i WITH 0 = 0
这基本上会导致交叉连接。这在给定情况下是否是个好主意是另一个问题,但我遇到过这确实非常有用的情况。
我正在尝试将这个我认为简单的 mysql 查询转换为 Doctrine dql,但是,我现在遇到了很大的困难...
SELECT (c.prix-aggregates.AVG) AS test
FROM immobilier_ad_blank c
CROSS JOIN (
SELECT AVG(prix) AS AVG
FROM immobilier_ad_blank)
AS aggregates
这样做的目的:创建 z 分数。 来自这个问题的原始实现 Calculating Z-Score for each row in MySQL? (simple)
我考虑过在实体内创建关联,但我的意思是它没有必要,它仅用于统计。
编辑:顺便说一句,我不想使用原始 SQL,我将使用 getDQL
从另一个查询构建器表达式中提取 "subquery"。否则,我将不得不重写我的动态查询构建器以考虑 rawSQL。
编辑 2: 试过这个
$subQb = $this->_em->createQueryBuilder();
$subQb->addSelect("AVG(subC.prix) as AMEAN")
->from("MomoaIntegrationBundle:sources\Common", "subC");
$subDql = $subQb->getDQL();
$dql = "SELECT c.prix FROM MomoaIntegrationBundle:sources\Common c INNER JOIN ($subDql) AS aggregates";
原始 dql 是:
SELECT c.prix FROM MomoaIntegrationBundle:sources\Common c INNER JOIN (SELECT AVG(subC.prix) as AMEAN FROM MomoaIntegrationBundle:sources\Common subC) AS aggregates
出现这个奇怪的错误:line 0, col 70 near '(SELECT AVG(subC.prix)': Error: Class '(' is not defined.
编辑 3: 我发现有点强硬的方式让它发挥作用,但学说对实体的实施很顽固,忘记了统计不需要实体!
$subQb = $this->_em->createQueryBuilder();
$subQb->addSelect("AVG(subC.prix) as AMEAN")
->from("MomoaIntegrationBundle:sources\Common", "subC");
$sql = "SELECT (c.prix-aggregates.sclr_0) AS test FROM immobilier_ad_blank c CROSS JOIN "
. "({$subQb->getQuery()->getSQL()}) AS aggregates";
$stm = $stm = $this->_em->getConnection()->prepare($sql);
$stm->execute();
$data = $stm->fetchAll();
如果您有更好的解决方案,我洗耳恭听!我实际上不喜欢这个解决方案。
对于复杂的查询,您可能需要考虑绕过 DQL 并使用本机查询 - 特别是因为您不需要实体中的结果。
$connection = $em->getConnection();
$statement = $connection->prepare("
select c.prix-aggregates, t1.avg
from immobilier_ad_blank
cross join (
select avg(prix) as avg
from immobilier_ad_blank
) t1
");
$statement->execute();
$results = $statement->fetchAll();
从 Doctrine 2.4 开始,可以在不使用已定义关联的情况下加入,例如:
SELECT u FROM User u JOIN Items i WITH u.age = i.price
这个没有任何意义,但你明白了。在这种情况下 WITH
关键字是绝对必需的,否则会出现语法错误,但您可以只提供一个虚拟条件,如下所示:
SELECT u FROM User u JOIN Items i WITH 0 = 0
这基本上会导致交叉连接。这在给定情况下是否是个好主意是另一个问题,但我遇到过这确实非常有用的情况。