Преобразование SQL в выражение Laravel Eloquent

Я работал над несколькими таблицами, в которых используются довольно сложные отношения (которые я пытаюсь очистить, но мне все еще нужны отчеты, сделанные на основе данных через мой Laravel).

На данный момент я могу получить данные, используя следующий запрос SQL к моей базе данных MySQL:

SELECT
customers.id,
customers.customer_name,
SUM(shipments.balance) AS shipmentBalance

FROM customers

LEFT JOIN shipments 
ON customers.id = shipments.bill_to  
AND balance > (SELECT IFNULL(SUM(payments_distributions.amount),0)                
    FROM payments_distributions               
    WHERE payments_distributions.shipment_id = pro_number)
GROUP BY customers.id, customers.customer_name
ORDER BY shipmentBalance DESC
LIMIT 5;

Я просто не уверен, как правильно переписать его в операторы whereRaw или DB :: raw, которые требует Laravel Eloquent, поскольку мои предыдущие попытки потерпели неудачу.

Обновлять

Вот самое близкое решение, которое я пробовал:

DB::table('customers')
        ->select('customers', DB::raw('SUM(shipments.balance) AS shipmentBalance'))
        ->leftJoin(
                 DB::raw('
                        (select shipments 
                        ON customers.id = shipments.bill_to
                        AND balance > (SELECT IFNULL(SUM(payments_distributions.amount),0) 
                            FROM payments_distributions 
                            WHERE payments_distributions.shipment_id = pro_number)'))
        ->groupBy('customers.id')
        ->orderByRaw('shipmentBalance DESC')
        ->limit(5)
        ->get();

Обновление 2

Изменить для Dom:

Используя все изложенное в вашем ответе, я получаю следующий ответ:

SQLSTATE[42S22]: Column not found: 1054 Unknown column '' in 'on clause' (SQL: select customers.id, customers.customer_name,SUM(s.balance) AS shipmentBalance from `customers` left join `shipments` as `s` on `customers`.`id` = `s`.`bill_to` and s.balance > (SELECT IFNULL(SUM(payments_distributions.amount),0) FROM payments_distributions WHERE payments_distributions.shipment_id = s.pro_number) = `` group by `customers`.`id`, `customers`.`customer_name` order by SUM(s.balance) DESC limit 5)

Но если я удалю этот раздел, откроется страница и клиенты (правда, в неправильном порядке, поскольку я удалил один из необходимых компонентов:

$join->on(DB::raw('s.balance > 
            (SELECT IFNULL(SUM(payments_distributions.amount),0)                
            FROM payments_distributions               
            WHERE payments_distributions.shipment_id = s.pro_number)
                                            ')); 

Могу ли я предоставить вам что-нибудь, чтобы это конкретное утверждение работало со всем вашим ответом?

что ты уже испробовал?

Jonas Staudenmeir 27.04.2018 18:06

Я включил то, что, по моему мнению, было наиболее близким к лучшему, но все равно не повезло.

Matthew 27.04.2018 18:16

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

halfer 05.05.2018 20:51
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
1
3
73
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Преимущество начала с модели клиента заключается в том, что у вас будет коллекция laravel и вы можете разбивать на страницы по мере необходимости. Также просмотрите красноречивые документы, они помогут вам понять все различные варианты. Надеюсь, он поможет.

P.S. Начните с использования вашей модели в вашем контроллере или везде, где вы размещаете этот запрос:

use App\Customer

Запрос

$theQuery = Customer::select(DB::raw('customers.id, customers.customer_name,SUM(s.balance) AS shipmentBalance'))
        ->leftJoin('shipments as s', function($join)
        {
            $join->on('customers.id', '=', 's.bill_to');
            $join->on(DB::raw('s.balance > 
                                (SELECT IFNULL(SUM(payments_distributions.amount),0)                
                                    FROM payments_distributions               
                                    WHERE payments_distributions.shipment_id = s.pro_number)
                            '));    
        })
        ->groupBy('customers.id', 'customers.customer_name')
        ->orderByRaw('SUM(s.balance) DESC')
        ->limit(5)
        ->get();

Я отредактировал свой вопрос, так как получил ошибку, возникающую во втором из внутренних соединений. Могу я предоставить вам дополнительную информацию, которая может помочь вам с этой новой ошибкой? Еще раз спасибо - Мэтт

Matthew 27.04.2018 21:08

@Ma Что он получает, когда вы его запрашиваете? А где определяется pro_number? (ВЫБЕРИТЕ IFNULL (SUM (payments_distributions.amount), 0) FROM payments_distributions ГДЕ payments_distributions.shipment_id = pro_number)

Dom DaFonte 27.04.2018 21:12

pro_number берется из таблицы отгрузок. Хотя, если я вставлю то, что вы отправили, как вы это отправили, я ничего не верну, и я думаю, это из-за JOIN, который требуется между отправками и payments_distributions.

Matthew 27.04.2018 21:18

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

Dom DaFonte 27.04.2018 21:20

@Matthew У вас была возможность попробовать предоставленный мной запрос Eloquent? Сообщите мне, если это решит проблему.

Dom DaFonte 27.04.2018 22:12
Ответ принят как подходящий

Использовать это:

DB::table('customers')
    ->select('customers.id', 'customers.customer_name', DB::raw('SUM(shipments.balance) AS shipmentBalance'))
    ->leftJoin('shipments', function($join) {
        $join->on('customers.id', 'shipments.bill_to')
            ->where('balance', '>', function($query) {
                $query->selectRaw('IFNULL(SUM(payments_distributions.amount),0)')
                    ->from('payments_distributions')
                    ->where('payments_distributions.shipment_id', DB::raw('pro_number'));
            });
    })
    ->groupBy('customers.id', 'customers.customer_name')
    ->orderByDesc('shipmentBalance')
    ->limit(5)
    ->get();

Другие вопросы по теме