I was trying to join two columns in tables that used different collation using Zend Db and I got this error:
Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8_unicode_ci,IMPLICIT) for operation '=')
After googling and finding a few questions on Stackoverflow I added COLLATE utf8_unicode_ci
onto my join like so:
$select = $this->getSql()->select();
$select->columns(['*', new Expression('count(*) as count')]);
$select->join(
['tbl2' => 'table2'],
'table1.name COLLATE utf8_unicode_ci = tbl2.name',
['person_id' => 'id'],
$select::JOIN_LEFT
);
But now I get a different error:
...
could not be executed (42000 - 1064 - You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for
the right syntax to use near '`COLLATE` `utf8_unicode_ci`
This is because Zend automatically backquotes the keyword COLLATE
for me but I want to use a reserved word in the join
condition.
Ideally you should change your collation so that both match, then you can join those tables using that condition without the COLLATE
keyword. I'm not sure but I would guess using COLLATE
in a join will probably impact performance.
If you cannot change the schema then alternatively, you could use Predicate\Expression
instead on a string join which seems to bypass the auto quoting:
$select = $this->getSql()->select();
$select->columns(['*', new Expression('count(*) as count')]);
$select->join(
['tbl2' => 'table2'],
new \Zend\Db\Sql\Predicate\Expression('table1.name COLLATE utf8_unicode_ci = table2.name'),
['person_id' => 'id'],
$select::JOIN_LEFT
);
Or I guess you can bypass using Zend and handwrite the SQL statement yourself..