简体   繁体   English

Dctrine DQL连接可为空的列

[英]Doctrine DQL join on nullable columns

Is it possible to join two tables based on a null-able column with the Doctrine QueryBuilder? 是否可以使用Doctrine QueryBuilder联接基于可空列的两个表?

Using the default equality operator in Doctrine, translates into the regular equality operator in MySQL which returns NULL when comparing two NULL values. 使用Doctrine中的默认相等运算符,将其转换为MySQL中的常规相等运算符,当比较两个NULL值时,该运算符将返回NULL

I can achieve this in plain MySQL with the null-safe operator . 我可以使用null-safe运算符在纯MySQL中实现此目的。

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

However, as I presume <=> is MySQL specific, there is no out-of-the-box support for this in Doctrine? 但是,由于我假定<=>是MySQL特定的,因此在Doctrine中是否没有对此的现成支持?

Using the following query has been tried, but is unfortunately too resource intensive as this applies to quite some columns. 已经尝试使用以下查询,但是不幸的是,这会占用大量资源,因为这适用于很多列。

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)

Solution 1 : Doctrine Native SQL 解决方案1:Doctrine本机SQL

One way to achieve this is by using native MySQL queries. 实现此目的的一种方法是使用本机MySQL查询。 This require the use of Doctrine's Native SQL feature and mapping the results of the query using a ResultSetMapping . 这要求使用Doctrine的本机SQL功能,并使用ResultSetMapping映射查询结果。

I came across an issue when executing a Native SQL query twice (with different parameters), that the second query's result-set was the same as the first one. 当执行两次本机SQL查询(使用不同的参数)时,遇到一个问题,第二个查询的结果集与第一个查询的结果集相同。 Following post on GitHub solved this for me. GitHub上的以下帖子为我解决了这个问题。

Solution 2 : Using MySQL's internal optimizer 解决方案2:使用MySQL的内部优化器

Using following join condition will use MySQL's internal optimizer and treat this as an ref_or_null join-type 使用以下ref_or_null条件将使用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)

It is then possible to use this join-condition in DQL, which will be translated nicely in SQL to be optimized. 然后可以在DQL中使用此连接条件,它将在SQL中很好地转换以进行优化。

Solution 3 : Write Custom DQL function 解决方案3:编写自定义DQL函数

I wrote a custom DQL-function that translated in the following clause: 我编写了一个自定义的DQL函数,该函数在以下子句中进行了翻译:

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

Unfortunately is was not able to get rid of the = 1 part of this clause. 不幸的是无法摆脱这一条款的= 1部分。 This worked, but caused a major performance impact on my query: 17s vs 0.5s, to give some (non-scientific) indication. 这行得通,但是对我的查询产生了重大的性能影响:17s vs 0.5s给出了一些(非科学的)指示。
So i didn't go further down that road. 所以我没有走这条路。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM