是否可以基于具有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)
答案 0 :(得分:1)
实现此目的的一种方法是使用本机MySQL查询。 这需要使用Doctrine's Native SQL功能并使用ResultSetMapping映射查询结果。
我在执行Native SQL查询两次(使用不同的参数)时遇到了一个问题,即第二个查询的结果集与第一个查询的结果集相同。 Following post on GitHub为我解决了这个问题。
使用以下连接条件将使用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中很好地转换为优化。
我编写了一个自定义DQL函数,该函数在以下子句中翻译:
SELECT a.*, b.*
FROM a
INNER JOIN b ON (a.column <=> b.column) = 1
不幸的是,无法摆脱本条款的= 1
部分。这有效,但是对我的查询造成主要性能影响:17s vs 0.5s,给出一些(非科学)指示。
所以我没有走得更远。