Объедините два запроса в один в Laravel Query Builder или SQL

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

В настоящее время я делаю два следующих запроса и объединяю их после.

 $acc_id = 10;
 $locat_id= 3;  

//First get all sites with account id
$allSites = collect(DB::table('sites')->where('acc_id', $acc_id)->get()):

//Next get only sites with account id and connections with current location id
$connectedSites = collect( 
    DB::table('sites')
        ->select('sites.id','name','active','url')
        ->join('connections as conn','sites.id','=','conn.site_id')
        ->where('acc_id',$acc_id)
        ->where('conn.locat_id',$locat_id)
        ->get()
);

//Merge the collections and drop first row with duplicate site_id
$sites = $allSites->merge($connectedSites)->keyBy('id');

return $sites;

Так что это дает мне желаемые результаты. Например. все сайты, связанные с идентификатором учетной записи, а также данные подключения для сайтов, связанных как с идентификатором учетной записи, так и с идентификатором местоположения. Однако я хотел бы узнать, как это сделать в одном запросе, если это возможно.

У каждого сайта есть хотя бы одно соединение?

Jonas Staudenmeir 16.03.2018 21:54

Нет на некоторых сайтах нет связи. Они (сайты) добавляются по умолчанию при создании учетной записи. Подключения выполняются пользователем позже.

skribe 16.03.2018 21:56

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

skribe 16.03.2018 21:58
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
3
1 969
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это можно сделать с помощью одного запроса, но я использую Eloquent вместо конструктора запросов. Обратите внимание на метод with (), он позволяет загружать отношения.

$sites = Sites::with('connections')->where('acc_id', $acc_id)->get();

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

foreach($sites as $site){
    $site->connection->stuff; // No query generated
}

если вам нужно разделить два, это тоже легко.

$connectedSites = $sites->where('connection.locat_id', $locat_id)
// No query generated from the above, but now $connectedSites has all of
// the connected sites

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

https://laravel.com/docs/5.6/collections#available-methods

Спасибо за это. Я часто использую Eloquent для отдельных запросов, и мне очень нравятся коллекции и все методы, которые предоставляет laravel для работы с ними. Ваши предложения действительно могут сработать, однако моя настоящая цель - научиться строить запрос на чем-то более похожем на SQL.

skribe 16.03.2018 21:49

Ах я вижу. К сожалению, у меня гораздо лучше с красноречием, чем с SQL. Надеюсь, ты найдешь свой ответ.

N Mahurin 16.03.2018 22:49
Ответ принят как подходящий

Попробуйте LEFT JOIN:

$sites = DB::table('sites')
    ->select('sites.*','name','active','url')
    ->leftJoin('connections as conn', function($query) use($locat_id) {
        $query->on('sites.id', '=', 'conn.site_id')
            ->where('conn.locat_id', $locat_id);
    })
    ->where('acc_id',$acc_id)
    ->get();

Левое соединение по-прежнему не возвращает все записи с $ acc_id. Только те, у которых есть и $ acc_id, и $ locat_id.

skribe 16.03.2018 21:39

На самом деле, я думаю, это работает. Но $ locat_id вне области видимости или что-то в этом роде и, похоже, не передается в функцию. Он работает, если я жестко запрограммировал его как ->where('conn.locate_id, 3) `но не, если я использую ->where('conn.locate_id, $ locat_id)`

skribe 16.03.2018 22:23

Извините, я исправил свой ответ.

Jonas Staudenmeir 16.03.2018 22:36

Я пропустил заявление use, когда впервые посмотрел на ваше исправление. :) Это довольно круто. Я понятия не имел, что вы можете использовать такие функции в запросе, как этот. Похоже, это дает те же результаты, что и то, что я делал с моим решением с двумя запросами. Бесконечно благодарен!

skribe 16.03.2018 22:43

Есть идеи, куда я могу пойти почитать, чтобы лучше понять, что там происходит?

skribe 16.03.2018 22:44

Вы имеете в виду SQL в целом или конструктор запросов Laravel?

Jonas Staudenmeir 16.03.2018 22:49

Я имел в виду использование функций в запросах. Это то, с чем я раньше не сталкивался. Где-нибудь, чтобы увидеть больше примеров, конкретных вариантов использования и т. д.

skribe 17.03.2018 08:49

Вы также можете использовать замыкания для создания сложных ограничений where.

Jonas Staudenmeir 17.03.2018 15:07

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