将原始 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的主要内容,如果未能解决你的问题,请参考以下文章

将Stata代码翻译成R

Doctrine Query Language 获取每组的最大/最新行

如何将 Aurora Mysql ddl 翻译成 Redshift ddl

如何将 PostgreSQL“merge_db”(又名 upsert)函数翻译成 MySQL

Symfony2/Doctrine:如何从实体类中持久化一个实体?

用python做一个文本翻译器,自动将中文翻译成英文,超方便的