Звезда не активнаЗвезда не активнаЗвезда не активнаЗвезда не активнаЗвезда не активна
 

Построение запросов Yii2

Построение запросов

Создав объект [[yii\db\Query]], вы можете вызвать различные методы для создания различных частей SQL выражения. Имена методов напоминают ключевые слова SQL, используемые в соответствующих частях SQL запроса. Например, чтобы указать FROM часть запроса, вам нужно вызвать метод [[yii\db\Query::from()|from()]]. Все методы построителя запросов возвращают свой объект, который позволяет объединять несколько вызовов в цепочку.



Далее будет описание каждого метода построителя запросов.

[[yii\db\Query::select()|select()]]

Метод [[yii\db\Query::select()|select()]] определяет фрагмент SELECT SQL запроса. Вы можете указать столбцы, которые должны быть выбраны, они должны быть указаны в виде массива или строки. Имена столбцов автоматически экранируются при создании SQL-запроса при его генерации из объекта [[yii\db\Query]].

$query->select(['id', 'email']);

// эквивалентно:

$query->select('id, email');

Имена столбцов могут быть выбраны вместе с префиксами таблиц и/или алиасами столбцов, также как при записи обычного SQL выражения. Например,

$query->select(['user.id AS user_id', 'email']);

// эквивалентно:

$query->select('user.id AS user_id, email');

Если вы используете формат массива для указания столбцов, вы можете также указать ключи массива для указания алиасов столбцов. Например, приведённый выше код может быть переписан:

$query->select(['user_id' => 'user.id', 'email']);

Если вы не вызываете метод [[yii\db\Query::select()|select()]] при создании запроса, будет использована *, что означает выбрать все столбцы.

Кроме имён столбцов, вы можете также использовать SQL выражения. Вы должны использовать формат массива для использования выражений, которые содержат запятые для предотвращения некорректного автоматического экранирования. Например,

$query->select(["CONCAT(first_name, ' ', last_name) AS full_name", 'email']);

Начиная с версии 2.0.1, вы также можете использовать подзапросы. Вы должны указывать каждый подзапрос в выражении как объект [[yii\db\Query]]. Например,

$subQuery = (new Query())->select('COUNT(*)')->from('user');

// SELECT `id`, (SELECT COUNT(*) FROM `user`) AS `count` FROM `post`
$query = (new Query())->select(['id', 'count' => $subQuery])->from('post');

Чтобы выбрать конкретные строки, вы можете вызвать метод [[yii\db\Query::distinct()|distinct()]]:

// SELECT DISTINCT `user_id` ...
$query->select('user_id')->distinct();

Вы можете вызвать [[yii\db\Query::addSelect()|addSelect()]] для добавления полей. Например,

$query->select(['id', 'username'])
    ->addSelect(['email']);

[[yii\db\Query::orderBy()|orderBy()]]

Метод [[yii\db\Query::orderBy()|orderBy()]] определяет фрагмент ORDER BY SQL выражения. Например,

// ... ORDER BY `id` ASC, `name` DESC
$query->orderBy([
    'id' => SORT_ASC,
    'name' => SORT_DESC,
]);

В данном коде, ключи массива - это имена столбцов, а значения массива - это соответствующее направление сортировки. PHP константа SORT_ASC определяет сортировку по возрастанию и SORT_DESC сортировка по умолчанию.

Если ORDER BY содержит только простые имена столбцов, вы можете определить их с помощью столбцов, также как и при написании обычного SQL. Например,

$query->orderBy('id ASC, name DESC');

Note: Вы должны использовать массив для указания ORDER BY содержащих выражения БД.

Вы можете вызывать [[yii\db\Query::addOrderBy()|addOrderBy()]] для добавления столбцов в фрагмент ORDER BY.

$query->orderBy('id ASC')
    ->addOrderBy('name DESC');

[[yii\db\Query::groupBy()|groupBy()]]

Метод [[yii\db\Query::groupBy()|groupBy()]] определяет фрагмент GROUP BY SQL запроса.

// ... GROUP BY `id`, `status`
$query->groupBy(['id', 'status']);

Если фрагмент GROUP BY содержит только простые имена столбцов, вы можете указать их используя строку, также как в обычном SQL выражении.

$query->groupBy('id, status');

Note: Вы должны использовать массив для указания GROUP BY содержащих выражения БД.

Вы можете вызывать [[yii\db\Query::addGroupBy()|addGroupBy()]] для добавления имён столбцов в фрагмент GROUP BY. For example,

$query->groupBy(['id', 'status'])
    ->addGroupBy('age');

[[yii\db\Query::having()|having()]]

Метод [[yii\db\Query::having()|having()]] определяет фрагмент HAVING SQL запроса. Он принимает условия, которое может быть определено тем же способом, что и для where().

// ... HAVING `status` = 1
$query->having(['status' => 1]);

Пожалуйста, обратитесь к документации для where() для более подробной информации о определении условий.

Вы можете вызывать [[yii\db\Query::andHaving()|andHaving()]] или [[yii\db\Query::orHaving()|orHaving()]] для добавления дополнительных условий в фрагмент HAVING.

// ... HAVING (`status` = 1) AND (`age` > 30)
$query->having(['status' => 1])
    ->andHaving(['>', 'age', 30]);

[[yii\db\Query::limit()|limit()]] и [[yii\db\Query::offset()|offset()]]

Методы [[yii\db\Query::limit()|limit()]] и [[yii\db\Query::offset()|offset()]] определяют фрагменты LIMIT и OFFSET SQL запроса.

// ... LIMIT 10 OFFSET 20
$query->limit(10)->offset(20);

Если вы определяете неправильный limit или offset (например отрицательное значение), они будут проигнорированы.

Info: Для СУБД, которые не поддерживают LIMIT и OFFSET (такие как MSSQL), построитель запросов будет генерировать SQL выражения, которые эмулирует поведение LIMIT/OFFSET.

[[yii\db\Query::join()|join()]]

Метод [[yii\db\Query::join()|join()]] определяет фрагмент JOIN SQL запроса.

// ... LEFT JOIN `post` ON `post`.`user_id` = `user`.`id`
$query->join('LEFT JOIN', 'post', 'post.user_id = user.id');

Метод [[yii\db\Query::join()|join()]] принимает четыре параметра:

  • $type: тип объединения, например, 'INNER JOIN', 'LEFT JOIN'.
  • $table: имя таблицы, которая должна быть присоединена.
  • $on: необязательное условие объединения, то есть фрагмент ON. Пожалуйста, обратитесь к документации для where() для более подробной информации о определении условий. Отметим, что синтаксис массивов не работает для задания условий для столбцов, то есть ['user.id' => 'comment.userId'] будет означать условие, где ID пользователя должен быть равен строке 'comment.userId'. Вместо этого стоит указывать условие в виде строки 'user.id = comment.userId'.
  • $params: необязательные параметры присоединяемые к условию объединения.

Вы можете использовать следующие сокращающие методы для указания INNER JOIN, LEFT JOIN и RIGHT JOIN, в указанном порядке.

  • [[yii\db\Query::innerJoin()|innerJoin()]]
  • [[yii\db\Query::leftJoin()|leftJoin()]]
  • [[yii\db\Query::rightJoin()|rightJoin()]]

Например,

$query->leftJoin('post', 'post.user_id = user.id');

Для соединения с несколькими таблицами, вызовите вышеуказанные методы несколько раз.

Кроме соединения с таблицами, вы можете также присоединять подзапросы. Чтобы это сделать, укажите объединяемый подзапрос как объект [[yii\db\Query]].

$subQuery = (new \yii\db\Query())->from('post');
$query->leftJoin(['u' => $subQuery], 'u.id = author_id');

В этом случае, вы должны передать подзапросы в массиве и использовать ключи для определения алиасов.

[[yii\db\Query::union()|union()]]

Метод [[yii\db\Query::union()|union()]] определяет фрагмент UNION SQL запроса.

$query1 = (new \yii\db\Query())
    ->select("id, category_id AS type, name")
    ->from('post')
    ->limit(10);

$query2 = (new \yii\db\Query())
    ->select('id, type, name')
    ->from('user')
    ->limit(10);

$query1->union($query2);

Вы можете вызвать [[yii\db\Query::union()|union()]] несколько раз для присоединения фрагментов UNION.

Заберите ссылку на статью к себе, чтобы потом легко её найти ;)

Выберите, то, чем пользуетесь чаще всего:

Спасибо за внимание, оставайтесь на связи! Ниже ссылка на форум и обсуждение ; )


Обсудить эту статью

INFO: Вы отправляете сообщение как 'Гость'