Jelly — Пишем сложные запросы

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

То тут, мы не знаем как написать простейших запрос для подсчёта суммы, без вынимания всех значений, то там, мы не можем составить нетривиальное условие.

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

Сегодня я хочу рассказать, как мы можем обойти часть сложностей и упростить себе работу и, возможно, снизить нагрузку на сервер, используя ORM Jelly.

Выбираем только нужные нам поля

Для указания какие поля нам нужно возратить в кортеже, можно использовать функцию select()

Например:
``

// Простая выборка только нужных полей
Jelly::select(‘user’)
        ->select(‘id’,‘name’)
        -execute();

// Выбираем все поля Jelly::select(‘user’) ->select(’*‘) -execute();

// Суммируем значения по колонке Jelly::select(‘transactions’) ->select(‘title’, DB::expr(“SUM(‘money’) AS money”)) -execute();

// Выбираем все колонки из одной таблицы, и избранные из другой Jelly::select(‘user’) ->select(DB::expr(’users.*‘), DB::expr(”providers.id AS provider_id”)) -execute();

``

Тут важно помнить, что если какие-то из полей в кортеже у нас не были описаны в модели, то и доступ к ним мы получить привычным способом не сможем.
Для этого нам нужно использовать функцию get('field')

Как-то так:
`

// Суммируем значения по колонке
$transactions = Jelly::select(‘transactions’)
        ->select(‘title’, DB::expr(“SUM(‘money’) AS money”))
        ->execute();

// Выводим сумму foreach ($transactions as $transaction) { echo $transaction->title . “ ” . $transactions->get(‘money’); }

`

То что нужно знать

Конечно же, вы должны уже знать как можно группировать условия логически и умеете пользоваться операторами JOIN и WITH (про них описано в официальной справке, если что).

Например вот этот поток сознания вам поможет сориентироваться в обстановке
</p> <pre lang="php"> $builder = Jelly::select('users') ->join('provider', 'left') ->on('provider.user_id', '=', 'user.id') ->on('provider.name', 'LIKE', 'NBN%') ->where('date_reg', '>', '2010-01-01') ->and_where('active', '=', 1) ->or_where_open() ->where('admin', '=', 1) ->or_where_close() ->execute(); </pre> <p>

До того как вы вызовете execute() или load() вы всегда можете посмотреть что у нас получается в билдере запросов. Для этого его можно просто вывести на печать.

`

$builder = Jelly::select(‘users’)
        ->where(‘date_reg’, ‘>’, ‘2010-01-01’);

// Выводим получившийся запрос print $builder;

$users = $builder->execute();

`

Так же, важно знать что код обёрнутый DB::expr('code') не обрабатывается билдером. Что позволяет нам транслировать в него прямые куски SQL кода.

Подзапросы

Теперь можно попробовать составить что-то необычное, например подзапросы. Внимание, лучше сесть :)
`</p> <pre lang="php"> $subquery = Jelly::select('price') ->select(DB::expr('SUM(price.spec) ASspec')) ->where('providers.id', '=', DB::expr('price.provider_id')) ->and_where('price.group_id', '=', DB::expr('groups.group_id`‘));

$builder = Jelly::select(‘user’) ->select(’provider.*‘, DB::expr(‘(’.$subquery . ‘) AS spec’)) ->distinct(TRUE) ->order_by(‘spec’, ‘DESC’) ->execute();

``

Этот код не обладает красотой и теми плюшечками ORM которые нам предоставлены из коробки, но именно этот код позволяет писать гибкие запросы.

Read more posts by this author.