带有联接的 Doctrine 查询生成器会导致:“‘on 子句’中的未知列 id”
总结
我正在尝试使用 Doctrine 的查询生成器来创建包含多个联接的 SELECT。
当所有联接都是通过实体关系完成时,这种方法工作得很好,但是当我不通过关系引入联接(下面的campaign_instance
)时,它会导致错误的 MySQL 查询。
错误是“‘on 子句’中存在未知列‘w3_.id’
”。 w3_
指的是绝对具有 id
列的表。
代码
此查询构建器:
$this->entity_manager->getRepository(CampaignStep::class)
->createQueryBuilder('campgain_steps_available_for_completion')
->select('step')
->from(CampaignStep::class, 'step')
->join('step.group', 'campaign_group')
->join('campaign_group.campaign', 'campaign')
->join(
CampaignInstance::class,
'campaign_instance',
'WITH',
'campaign_instance.campaign = campaign')
->getQuery()
->execute();
导致此 MySQL 查询:
SELECT
t0_.id AS id_0,
t0_.slug AS slug_1,
t0_.description AS description_2,
t0_.active AS active_3,
t0_.created_at AS created_at_4,
t0_.step_completion_min AS step_completion_min_5,
t0_.ordinal AS ordinal_6,
t0_.dtype AS dtype_7,
t0_.mobile_image_id AS mobile_image_id_8,
t0_.web_image_id AS web_image_id_9,
t0_.group_id AS group_id_10
FROM
taxonomy_topic t1_
INNER JOIN campaign_instance w2_ ON (w2_.campaign_id = w3_.id),
taxonomy_topic t0_
INNER JOIN campaign_group w4_ ON t0_.group_id = w4_.id
INNER JOIN campaign w3_ ON w4_.campaign_id = w3_.id
AND w3_.dtype IN ('campaign')
WHERE
(
t1_.dtype IN ('campaignstep')
AND t0_.dtype IN ('campaignstep')
)
...这会导致此错误:
Unknown column 'w3_.id' in 'on clause'
实体摘要
以下是实体关系:
Campaign
<-1-M->< /code>
CampaignGroup
<-1-M->
CampaignStep
Campaign
<-1 -M-
CampaignInstance
我选择 CampaignStep
,将它们加入 CampaignGroup
,然后通过其实体关系加入 Campaign
。就这么多了。
然后我想从 Campaign
加入到 CampaignInstance
。由于该关系是单向的(拥有侧 CampaignInstance
),因此我无法使用 Campaign
关系来到达那里。添加此:
->join(
CampaignInstance::class,
'campaign_instance',
'WITH',
'campaign_instance.campaign = campaign')
到查询生成器会破坏生成的查询。
我该如何解决这个问题?
Packages
composer showdoctrine/*
:
doctrine/annotations 1.13.2 Docblock Annotations Parser
doctrine/cache 1.12.1 PHP Doctrine Cache library is a popular cache implementation that supports ...
doctrine/collections 1.6.8 PHP Doctrine Collections library that adds additional functionality on top ...
doctrine/common 2.13.3 PHP Doctrine Common project is a library that provides additional functiona...
doctrine/dbal 2.13.7 Powerful PHP database abstraction layer (DBAL) with many features for datab...
doctrine/deprecations v0.5.3 A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging w...
doctrine/doctrine-bundle 2.3.2 Symfony DoctrineBundle
doctrine/doctrine-migrations-bundle 2.2.3 Symfony DoctrineMigrationsBundle
doctrine/event-manager 1.1.1 The Doctrine Event Manager is a simple PHP event system that was built to b...
doctrine/inflector 1.4.4 PHP Doctrine Inflector is a small library that can perform string manipulat...
doctrine/instantiator 1.4.0 A small, lightweight utility to instantiate objects in PHP without invoking...
doctrine/lexer 1.2.3 PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive D...
doctrine/migrations 2.3.5 PHP Doctrine Migrations project offer additional functionality on top of th...
doctrine/orm 2.7.5 Object-Relational-Mapper for PHP
doctrine/persistence 1.3.8 The Doctrine Persistence project is a set of shared interfaces and function...
doctrine/reflection 1.2.2 The Doctrine Reflection project is a simple library used by the various Doc...
doctrine/sql-formatter 1.1.2 a PHP SQL highlighting library
到目前为止我尝试过的:
这似乎与多个 FROM 子句有关。
如果我从 FROM (及其相关的 WHERE 子句)中删除第一个子句 taxonomy_topic t1_ INNER JOIN Workspace_instance w2_
,我会得到一个有效的查询,它准确地给出了我正在寻找的内容:
SELECT
t0_.id AS id_0,
t0_.slug AS slug_1,
t0_.description AS description_2,
t0_.active AS active_3,
t0_.created_at AS created_at_4,
t0_.step_completion_min AS step_completion_min_5,
t0_.ordinal AS ordinal_6,
t0_.dtype AS dtype_7,
t0_.mobile_image_id AS mobile_image_id_8,
t0_.web_image_id AS web_image_id_9,
t0_.group_id AS group_id_10
FROM
taxonomy_topic t0_
INNER JOIN workspace_group w4_ ON t0_.group_id = w4_.id
INNER JOIN workspace w3_ ON w4_.campaign_id = w3_.id
AND w3_.dtype IN ('campaign')
WHERE
(
t0_.dtype IN ('campaignstep')
)
但是,我不不知道如何更改 Doctrine Query Builder 以生成该 MySQL。
Summary
I'm trying to use Doctrine's Query Builder to make a SELECT that includes a number of joins.
This works fine when all the joins are done through entity relationships, but when I introduce a join not through a relationship (campaign_instance
below), it results in a bad MySQL query.
The error is "Unknown column 'w3_.id' in 'on clause'
". w3_
refers to a table that absolutely has an id
column.
The code
This query builder:
$this->entity_manager->getRepository(CampaignStep::class)
->createQueryBuilder('campgain_steps_available_for_completion')
->select('step')
->from(CampaignStep::class, 'step')
->join('step.group', 'campaign_group')
->join('campaign_group.campaign', 'campaign')
->join(
CampaignInstance::class,
'campaign_instance',
'WITH',
'campaign_instance.campaign = campaign')
->getQuery()
->execute();
results in this MySQL query:
SELECT
t0_.id AS id_0,
t0_.slug AS slug_1,
t0_.description AS description_2,
t0_.active AS active_3,
t0_.created_at AS created_at_4,
t0_.step_completion_min AS step_completion_min_5,
t0_.ordinal AS ordinal_6,
t0_.dtype AS dtype_7,
t0_.mobile_image_id AS mobile_image_id_8,
t0_.web_image_id AS web_image_id_9,
t0_.group_id AS group_id_10
FROM
taxonomy_topic t1_
INNER JOIN campaign_instance w2_ ON (w2_.campaign_id = w3_.id),
taxonomy_topic t0_
INNER JOIN campaign_group w4_ ON t0_.group_id = w4_.id
INNER JOIN campaign w3_ ON w4_.campaign_id = w3_.id
AND w3_.dtype IN ('campaign')
WHERE
(
t1_.dtype IN ('campaignstep')
AND t0_.dtype IN ('campaignstep')
)
...Which results in this error:
Unknown column 'w3_.id' in 'on clause'
Entity summary
Here are the entity relationships:
Campaign
<-1-M->
CampaignGroup
<-1-M->
CampaignStep
Campaign
<-1-M-
CampaignInstance
I'm selecting CampaignStep
s, joining them to CampaignGroup
then Campaign
through their entity relationships. That much works.
Then I want to join from Campaign
to CampaignInstance
. Since that relationship is unidirectional (owning side CampaignInstance
), I can't use a Campaign
relationship to get there. Adding this:
->join(
CampaignInstance::class,
'campaign_instance',
'WITH',
'campaign_instance.campaign = campaign')
to the Query Builder breaks the resulting query.
How do I fix this?
Packages
composer show doctrine/*
:
doctrine/annotations 1.13.2 Docblock Annotations Parser
doctrine/cache 1.12.1 PHP Doctrine Cache library is a popular cache implementation that supports ...
doctrine/collections 1.6.8 PHP Doctrine Collections library that adds additional functionality on top ...
doctrine/common 2.13.3 PHP Doctrine Common project is a library that provides additional functiona...
doctrine/dbal 2.13.7 Powerful PHP database abstraction layer (DBAL) with many features for datab...
doctrine/deprecations v0.5.3 A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging w...
doctrine/doctrine-bundle 2.3.2 Symfony DoctrineBundle
doctrine/doctrine-migrations-bundle 2.2.3 Symfony DoctrineMigrationsBundle
doctrine/event-manager 1.1.1 The Doctrine Event Manager is a simple PHP event system that was built to b...
doctrine/inflector 1.4.4 PHP Doctrine Inflector is a small library that can perform string manipulat...
doctrine/instantiator 1.4.0 A small, lightweight utility to instantiate objects in PHP without invoking...
doctrine/lexer 1.2.3 PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive D...
doctrine/migrations 2.3.5 PHP Doctrine Migrations project offer additional functionality on top of th...
doctrine/orm 2.7.5 Object-Relational-Mapper for PHP
doctrine/persistence 1.3.8 The Doctrine Persistence project is a set of shared interfaces and function...
doctrine/reflection 1.2.2 The Doctrine Reflection project is a simple library used by the various Doc...
doctrine/sql-formatter 1.1.2 a PHP SQL highlighting library
What I've tried so far:
This seems to have something to do with the multiple FROM clauses.
If I remove the first clause taxonomy_topic t1_ INNER JOIN workspace_instance w2_
from the FROM (and its related WHERE clause), I get a valid query that gives me exactly what I'm looking for:
SELECT
t0_.id AS id_0,
t0_.slug AS slug_1,
t0_.description AS description_2,
t0_.active AS active_3,
t0_.created_at AS created_at_4,
t0_.step_completion_min AS step_completion_min_5,
t0_.ordinal AS ordinal_6,
t0_.dtype AS dtype_7,
t0_.mobile_image_id AS mobile_image_id_8,
t0_.web_image_id AS web_image_id_9,
t0_.group_id AS group_id_10
FROM
taxonomy_topic t0_
INNER JOIN workspace_group w4_ ON t0_.group_id = w4_.id
INNER JOIN workspace w3_ ON w4_.campaign_id = w3_.id
AND w3_.dtype IN ('campaign')
WHERE
(
t0_.dtype IN ('campaignstep')
)
However, I don't know how to alter the Doctrine Query Builder to result in that MySQL.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
想通了。
由于我是从
CampaignStep
存储库创建查询生成器,因此CampaignStep
选择是隐式的。通过添加->select('step')->from(CampaignStep::class, 'step')
,它试图再次加入 CampaignStep,导致多个 FROM 子句破坏了询问。这是固定的查询生成器:
Figured it out.
Since I'm creating the Query Builder from the
CampaignStep
repository, theCampaignStep
select was implicit. By adding->select('step')->from(CampaignStep::class, 'step')
, it was trying to join CampaignStep again, resulting in the multiple FROM clauses that broke the query.This is the fixed Query Builder:
阅读 https://dev.mysql.com/doc/refman/8.0 /en/join.html 在其显示的部分中:
我不使用 Doctrine,因此我无法建议如何使其查询生成器执行您想要的操作。但是该手册页中记录的 JOIN 语义解释了为什么您会收到所看到的错误。
Read https://dev.mysql.com/doc/refman/8.0/en/join.html in the sections where it says:
I don't use Doctrine, so I can't advise on how to make its query builder do what you want. But the semantics of JOIN documented at that manual page explain why you got the errors you saw.