COLLECTION JOIN

CollectionJoin - этот класс содержит коллекцию экземпляров класса Join. Способен генерировать join фрагмент sql кода, содержащий множество подключений таблиц средствами join. Экземпляр класса получаем через фабрику (смотри раздел УСТАНОВКА).

Описание функций и методов

Метод Описание
__construct($settings) Экземпляр класса создается в фабрике и при создании в конструктор передается массив настроек (смотри раздел УСТАНОВКА).
addNew($mergeMethod, $table, $column, $outColumn) Создает экземпляр класса Join и добавляет в коллекцию. Затем возвращает сгенерированный псевдоним для таблицы.
  • $mergeMethod - тип соединения таблиц для join. Может принимать только одно из следующих значений: inner, left, right, full, cross.
  • $table - таблица, которую будем join’ить.
  • $column - столбец с внешним ключом из таблицы $table.
  • $outColumn - столбец таблицы с которой join’им, должен записываться вместе с псевдонимом таблицы.
    Пр: p.id, где:
    p – псевдоним таблицы с которой join’им
    id – имя колонки (первичный ключ)
add($join) Добавляет экземпляр класса Join в коллекцию и возвращает сгенерированный псевдоним для таблицы.
get($alias) Получить экземпляр класса Join из коллекции по псевдониму таблицы.
getAll() Получить всю коллекцию экземпляров класса Join.
getAllAlias() Получить все псевдонимы таблиц в коллекции.
getSql() Получить строку sql запроса, данные формируются после вызова функции generate().
getBind() Получить массив биндов. Данные формируются после вызова функции generate().
remove($alias) Удалить элемент коллекции по псевдониму таблицы.
generate() Генерирует sql и массив биндов.

Примеры

Пример 1

Cодержимое таблиц:

mark (m)
id student id lesson id mark
1 1 1 3
2 1 1 4
3 1 2 2
4 1 2 2
5 1 2 3
6 1 4 5
7 2 1 2
8 2 1 3
9 2 2 5
10 2 4 4
11 2 3 3
12 2 3 2
13 2 2 5
14 2 3 3
15 2 1 2
16 3 4 2
17 3 1 5
18 3 2 2
19 3 4 3
20 3 3 4
student (s)
id name semester number
1 Даша 1
2 Маша 4
3 Паша 2

Пользователь должен иметь возможность получить всех студентов, которые подходят под указанные им критерии, а именно пользователь указывает оценки и массив id предметов, у которых должна встречаться такая оценка.

// Функция принимает массив, где ключи - это оценки, а значения – массив id предметов, у которых
// должна встречаться такая оценка. На выходе функция возвращает экземпляр объекта CollectionJoin
function joinForMarks ($marks) {
    // Создаем экземпляры классов CollectionJoin и Join с помощью фабрики, подробнее
    // в документации в разделе УСТАНОВКА (здесь случай компонента для yii2).
    $cJn = Yii::$app->gp->collectionJoin();
    foreach ($marks as $mark => $lessonId) {
        $join = Yii::$app->gp->innerJoin('mark', 'student_id', 's.id');
        $join->linkAnd([[$join->getAlias() . '.mark', '=', $mark],
                        [$join->getAlias() . '.lesson_id', 'in', $lessonId]]);
        $cJn->add($join);
    }
    return $cJn;
}

$cJoin = joinForMarks(['2' => [1,2,3,4],
                       '5' => [1, 2]]);

$rez = $qr->sql("select s.name from student s
                inner join mark m on s.id = m.student_id
                /*join*/
                group by s.name")
         ->join('/*join*/', $cJoin)->sortDesc('name')->all();

// Представленные ниже 2 записи выполняют одно и тоже:
// join('/*join*/', $cJoin)
// sqlPart('/*join*/', $cJoin->generate()->getSql(), $cJoin->getBind())

В результате будет сгенерирован примерно следующий sql запрос:

select s.name from student s
inner join mark m on s.id = m.student_id
inner join mark m5 on s.id = m.student_id and m5.mark = 2 and m5.lesson_id in (1,2,3,4)
inner join mark m2 on s.id = m.student_id and m5.mark = 5 and m5.lesson_id in (1,2)
group by s.name

var_dump($rez));

// Результат:
[
  0 => ['NAME' => 'Паша']
  1 => ['NAME' => 'Маша']
]