Как выполнить запрос MySQL с использованием Laravel?

Как можно перевести следующий MySQL запрос: 

```sql
select * from crmLogBalance
inner join
(select id as tabId, diff as positive, 0 as negative from crmLogBalance where diff >= 0
union
select id as tabId, 0 as positive, diff as negative from crmLogBalance where diff < 0) as tab
on tabId = id
```
в код на PHP с использованием Eloquent ORM, где возникает проблема на этапе объединения запросов и отображается сообщение "Template cache file", при этом подробности ошибки не видны? 

Используется следующий код:

```php
try {
    $with = ['Partner'];
    $subQueryA = CRM\LogBalance::query()->select("id", "0 as positive", "diff as negative")->where('diff', '<', 0);
    $subQueryB = CRM\LogBalance::query()->select("id", "diff as positive", "0 as negative")->where('diff', '>=', 0)->union($subQueryA); // здесь дебаг останавливается. 
    $query = $query->with($with)->joinSub($subQueryB, 'posNeg', function (JoinClause $join) {
        $join->on(CRM\LogBalance::db().'.id', '=', 'posNeg.id');
    })->get();
} catch (\Exception $exception) {
    echo $exception;
}
```
  • 3 марта 2025 г. 13:24
Ответы на вопрос 1
Чтобы переписать ваш SQL-запрос в Laravel с использованием Eloquent ORM и избежать проблем с объединением запросов, можно скорректировать ваш код. Давайте рассмотрим, как это можно сделать, исправив некоторые моменты.

1. Убедитесь, что вы используете корректные названия классов и пространств имен (namespace).
2. Ваша переменная `$query` не определена перед использованием в `joinSub`. Вам нужно сначала задать базовый запрос.
3. Вы можете воспользоваться методом `selectRaw()` для определения псевдонимов полей.

Вот исправленный вариант вашего кода:

```php
use CRM\LogBalance; // Убедитесь, что вы импортируете нужные классы
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\JoinClause;

try {
    $with = ['Partner'];

    // Подзапрос для негативных значений
    $subQueryA = LogBalance::query()
        ->select(['id', \DB::raw("0 as positive"), 'diff as negative'])
        ->where('diff', '<', 0);
    
    // Подзапрос для позитивных значений и объединение
    $subQueryB = LogBalance::query()
        ->select(['id', 'diff as positive', \DB::raw("0 as negative")])
        ->where('diff', '>=', 0)
        ->union($subQueryA);
    
    // Главный запрос
    $query = LogBalance::query()
        ->with($with)
        ->joinSub($subQueryB, 'posNeg', function (JoinClause $join) {
            $join->on('log_balance.id', '=', 'posNeg.id'); // Обратитесь к таблице явно, если необходимо
        })
        ->select('log_balance.*', 'posNeg.positive', 'posNeg.negative') // Выберите необходимые поля
        ->get();
    
    // Возвращение результатов
    return $query;

} catch (\Exception $exception) {
    // Логирование исключения или вывод сообщений об ошибках
    echo $exception->getMessage();
}
```

### Обратите внимание на следующее:

- Используйте `\DB::raw()` для создания псевдонимов полей в запросах `select()` для подзапросов.
- Убедитесь, что в вашей базе данных название таблицы `log_balance` действительно соответствует вашему классу `LogBalance`, либо уточняйте именно это имя в запросах.
- Чтобы избежать непредвиденных ошибок, лучше всегда отлавливать исключения и выводить информацию о них, чтобы диагностировать проблемы. В данном примере при возникновении исключения выводится сообщение об ошибке.
- Проверьте конфигурации проекта на наличие кеша шаблонов, возможно, следует очистить кеш с помощью команды `php artisan config:cache` или аналогичной в зависимости от ситуации.
Похожие вопросы