将原始 MySQL 翻译成 Doctrine 1.2
Posted
技术标签:
【中文标题】将原始 MySQL 翻译成 Doctrine 1.2【英文标题】:translate raw MySQL into Doctrine 1.2 【发布时间】:2011-12-23 15:15:51 【问题描述】:我正忙着将以下经过测试且运行良好的原始 mysql 查询转换为原则 1.2:
SELECT
r.name AS regionname,
s.name AS statename
FROM
job j
LEFT JOIN
community c ON c.id = j.community_id
LEFT JOIN
state s ON s.id = c.state_id
LEFT JOIN
region r ON r.id = s.region_id
WHERE
r.id = 1
这不起作用:
$q = Doctrine_Query::create()
->select('r.name AS regionname', 's.name AS statename')
->from('job j')
->leftJoin('community c ON c.id = j.community_id')
->leftJoin('state s ON s.id = c.state_id')
->leftJoin('region r ON r.id = s.region_id')
->where('r.id = 1')
->execute();
这是我的数据库结构,如果有用的话:
job:
columns:
id
community_id
relations:
community: local_key: community_id, foreign_key: id, foreignAlias: Communitys
community:
columns:
id
state_id
relations:
state: local_key: state_id, foreign_key: id, foreignAlias: States
state:
columns:
id
name
region_id
relations:
region: local_key: region_id, foreign_key: id, foreignAlias: Regions
region:
columns:
id
name
【问题讨论】:
【参考方案1】:我也注意到了同样的事情。在 Doctrine 1.2 中进行连接与 mysql 有点不同。要进行连接,您必须利用 Doctrine 在您的案例作业类中的每个组件中创建的关系。
您可以检查作业的基类以了解我所说的这些关系。在 setup 方法中,例如对于作业表中的社区外键 ID,它们看起来像这样:
$this->hasOne('community as Communitys', array(
'local' => 'community_id',
'foreign' => 'id'));
回到您的问题,要进行连接,您必须引用外键所属表的别名。例如,如果您想使用别名 Community 加入社区表:
->leftJoin('j.Community')
而不是
community c ON c.id = j.community_id
请注意,我没有说 join on id 因为在 Doctrine 1.2 中已经暗示了这一点。但是,您可以选择加入其他内容。
同样,如果您之前加入的表需要加入到其他表中,那么它们对您有外键
1.在当前查询中使用他们的别名并且 2.reference the component as described in THEIR base class as well。
所以你说你想以你应该这样做的方式加入社区到当前查询中的状态
// join job and community first
->from('job j')
->leftJoin('j.Community c')
// join community to state since they are the ones that are related
->leftjoin('c.States s')
从这里我希望你能看到模式。归根结底,如果你看一下,加入的想法仍然与原始 sql 相同,唯一的区别是语法:
SQL 语法:
LEFT JOIN
community c ON c.id = j.community_id
DQL 语法:
->leftJoin('j.Community c')
无论如何回答你的问题,这里是应该如何完成连接:
$q = Doctrine_Query::create()
->select('*')
->from('job j')
->leftJoin('j.Community c')
->leftJoin('c.State s')
->leftJoin('s.Region r')
->where('r.id = 1')
->execute();
【讨论】:
感谢您的详细回答。不幸的是,它不起作用。我也试图关闭外国别名,但它被挂断了。这是我在尝试使用它们时遇到的错误:“未知关系别名社区”每当我尝试其中任何一个时都会遇到这些错误。我将检查它们在设置方法中的内容并重新发布。再次感谢。 ...这似乎是问题所在。没有“社区作为社区”声明,只有“社区,数组(”。这让我有点困惑,因为我的架构确实将其声明为外来别名。但我的架构并未将其识别为一对一的关系。是这个问题吗? 更新:我更改了基类以包含“as”子句(我知道这是错误的形式,如果它最终纠正了问题,我将在架构中更改它)并且它确实修复了“社区”关系的问题,但是,它现在挂在“状态”子句上,给我一个错误,说工作必须与状态相关......它在我的架构中没有......社区与国家有关。有解决方案的想法吗? 更新 2:仅供参考,在我更新了我的基类以包含“as”子句后,它破坏了我的应用程序中所有以前键入“community”的查询,所以它看起来不像将关系更新为一对一是解决方案。 抱歉回复晚了。我现在才看到这个,我们的时区可能有所不同。您可以在这里发布您的 Job 基类吗?以上是关于将原始 MySQL 翻译成 Doctrine 1.2的主要内容,如果未能解决你的问题,请参考以下文章
Doctrine Query Language 获取每组的最大/最新行
如何将 Aurora Mysql ddl 翻译成 Redshift ddl
如何将 PostgreSQL“merge_db”(又名 upsert)函数翻译成 MySQL