Search code examples
sqljoinzend-framework2quotingzend-db-select

Issue with quoting of IS, NULL, NOT, !, and other reserved strings in ON conditions of JOIN clauses in Zend Framework 2


I have an SQL statement, that selets sport classes/courses (courses) with their trainers (trainers) over an association table (courses_trainers). Since some courses have multiple trainers, I use the GROUP_CONCAT(...) function to get the trainer names into one field. Some trainers rows are empty or NULL, so I add a trainers.name IS NOT NULL and a trainers.name != "" condition to the ON clause of the trainers JOIN:

SQL statement

SELECT
    courses.id AS id,
    GROUP_CONCAT(DISTINCT trainers.name SEPARATOR "|||") AS trainers
    ...
FROM
    courses
    ...
LEFT JOIN
    courses_trainers ON courses.id = courses_trainers.course_id
LEFT JOIN
    trainers ON trainer_id = trainers.id
    AND trainers.name IS NOT NULL
    AND trainers.name != ""
    ...
...
WHERE `courses`.`id` = '898'
GROUP BY
    courses.id
;

OO variant in the CourseTable class

public function findOnceByID($id) { 
    $concatDelimiter = self::CONCAT_DELIMITER;
    $select = new Select();
    ...
    $select->columns(array(
        'id', ...
    ));
    $select->from($this->tableGateway->getTable());
    $select
        ...
        ->join('courses_trainers', 'courses.id = courses_trainers.course_id', array(), Select::JOIN_LEFT)
        ->join('trainers', 'trainer_id = trainers.id AND trainers.name IS NOT NULL AND trainers.name != ""', array(
            'trainers' => new Expression('GROUP_CONCAT(DISTINCT trainers.name SEPARATOR "' . $concatDelimiter . '")')
            ), Select::JOIN_LEFT)
        ...
    ;
    $where
        ->equalTo('courses.id', $id)
    ;
    $select->where($where, Predicate::OP_AND);
    $select->group('courses.id');
    $resultSet = $this->tableGateway->selectWith($select);
    return $resultSet;
}

The generated JOIN code I get looks like this:

LEFT JOIN
    `courses_trainers` ON `courses`.`id` = `courses_trainers`.`course_id`
LEFT JOIN
    `trainers` ON `trainer_id` = `trainers`.`id`
    AND `trainers`.`name` `IS` `NOT` `NULL`
    AND `trainers`.`name` `!`= `"``"`

So, here is to much quoted.

How to "explain" to the ZF, that IS, NOT, " etc. should not be quoted?


Solution

  • The join method accepts an expression as its second parameter for the ON clause

    ->join('trainers', new Expression('trainer_id = trainers.id AND trainers.name IS NOT NULL AND trainers.name != ""'),