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;
Так что это дает мне желаемые результаты. Например. все сайты, связанные с идентификатором учетной записи, а также данные подключения для сайтов, связанных как с идентификатором учетной записи, так и с идентификатором местоположения. Однако я хотел бы узнать, как это сделать в одном запросе, если это возможно.
Нет на некоторых сайтах нет связи. Они (сайты) добавляются по умолчанию при создании учетной записи. Подключения выполняются пользователем позже.
Возможно, отчасти проблема может быть связана с плохим дизайном того, как отношения между таблицами работают с моей стороны. На данный момент он работает идеально, как мне нужно, но мне нравится улучшать вещи насколько это возможно.






Это можно сделать с помощью одного запроса, но я использую 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.
Ах я вижу. К сожалению, у меня гораздо лучше с красноречием, чем с SQL. Надеюсь, ты найдешь свой ответ.
Попробуйте 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.
На самом деле, я думаю, это работает. Но $ locat_id вне области видимости или что-то в этом роде и, похоже, не передается в функцию. Он работает, если я жестко запрограммировал его как ->where('conn.locate_id, 3) `но не, если я использую ->where('conn.locate_id, $ locat_id)`
Извините, я исправил свой ответ.
Я пропустил заявление use, когда впервые посмотрел на ваше исправление. :) Это довольно круто. Я понятия не имел, что вы можете использовать такие функции в запросе, как этот. Похоже, это дает те же результаты, что и то, что я делал с моим решением с двумя запросами. Бесконечно благодарен!
Есть идеи, куда я могу пойти почитать, чтобы лучше понять, что там происходит?
Вы имеете в виду SQL в целом или конструктор запросов Laravel?
Я имел в виду использование функций в запросах. Это то, с чем я раньше не сталкивался. Где-нибудь, чтобы увидеть больше примеров, конкретных вариантов использования и т. д.
Вы также можете использовать замыкания для создания сложных ограничений where.
У каждого сайта есть хотя бы одно соединение?