Doctrine DQL连接可空列

时间:2016-01-15 12:14:24

标签: php mysql doctrine-orm

是否可以基于具有Doctrine QueryBuilder的无空列来连接两个表?

使用Doctrine中的默认相等运算符,转换为MySQL中的常规相等运算符,在比较两个NULL值时返回NULL

我可以使用null-safe operator在普通的MySQL中实现这一点。

SELECT t1.name, t1.field, t2.field2
FROM table1 t1 
  LEFT OUTER JOIN table2 t2 ON (t2.field <=> t1.field)

但是,正如我假设<=>是特定于MySQL的,在Doctrine中没有对此的支持吗?

尝试使用以下查询,但遗憾的是资源过于密集,因为这适用于相当多的列。

SELECT t1.name, t1.field, t2.field2
FROM table1 t1 
  LEFT OUTER JOIN table2 t2 ON 
    (t2.field = t1.field AND t1.field IS NOT NULL) 
    OR (t2.field IS NULL AND t1.field IS NULL)

1 个答案:

答案 0 :(得分:1)

解决方案1:Doctrine Native SQL

实现此目的的一种方法是使用本机MySQL查询。 这需要使用Doctrine's Native SQL功能并使用ResultSetMapping映射查询结果。

我在执行Native SQL查询两次(使用不同的参数)时遇到了一个问题,即第二个查询的结果集与第一个查询的结果集相同。 Following post on GitHub为我解决了这个问题。

解决方案2:使用MySQL的内部优化器

使用以下连接条件将使用MySQL的内部优化器并将其视为ref_or_null连接类型

SELECT a.*, b.* 
FROM a
   INNER JOIN b ON 
       a.column = b.column 
       OR (a.column IS NULL AND b.column IS NULL)

然后可以在DQL中使用这个连接条件,它将在SQL中很好地转换为优化。

解决方案3:编写自定义DQL函数

我编写了一个自定义DQL函数,该函数在以下子句中翻译:

SELECT a.*, b.* 
FROM a
   INNER JOIN b ON (a.column <=> b.column) = 1

不幸的是,无法摆脱本条款的= 1部分。这有效,但是对我的查询造成主要性能影响:17s vs 0.5s,给出一些(非科学)指示。
所以我没有走得更远。