Laravel join и left join вместе в запросе

У меня есть sql-запрос, который я хочу преобразовать в построитель запросов или Laravel ORM. Работает нормально. Но я хочу, чтобы это было в форме конструктора запросов или ORM. Можно ли писать в конструкторе запросов или ORM ?.

У меня есть четыре таблицы ответов, вопросы, пользователи и upvote_answers. В запросе есть три «соединения» и одно «левое соединение», чтобы проверить, получил ли текущий авторизованный пользователь (логическое значение) ответ или нет, а также другие атрибуты.

   SELECT answers.answer_content as answer_content,
          answers.id as answer_id,
          answers.created_at as created_at,
          answers.created_at as answer_upvote,
          answers.created_at as answer_downvote,
          questions.id as question_id, 
          questions.question_title as question_title, 
          questions.question_slug as question_slug, 
          users.id as user_id, 
          users.name as user_name, 
          users.user_slug as user_slug,
          upvote_answers.upvote as upvote
                                        FROM 
                                            answers
                                            JOIN questions on questions.id = answers.question_id
                                            JOIN users on users.id = answers.user_id
                                            LEFT JOIN upvote_answers ON
                                                upvote_answers.answer_id = answers.id AND
                                                upvote_answers.user_id = '2'
                                        WHERE 
                                            questions.question_active = 1 and 
                                            answers.answer_active = 1

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

Meysam Mahmoodi 10.03.2018 13:28

как, скажите, пожалуйста?

user9452884 10.03.2018 13:29
Стоит ли изучать 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 и хотите разрабатывать...
1
2
3 170
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Использовать предложение присоединения

https://laravel.com/docs/master/queries#joins

Простой пример

$users = DB::table('users')
            ->join('contacts', 'users.id', '=', 'contacts.user_id')
            ->join('orders', 'users.id', '=', 'orders.user_id')
            ->select('users.*', 'contacts.phone', 'orders.price')
            ->where('users.id', '=', 100)
            ->get();

Также вы можете использовать предложение Left Join.

Обновлять:

$yourQuery = \DB::table('answers')
    ->join('questions', 'questions.id', '=', 'answers.question_id')
    ->join('users', 'users.id', '=', 'answers.user_id')
    ->leftJoin('upvote_answers', 'upvote_answers.answer_id', '=', 'answers.id')
    ->where('questions.question_active', '=', '1')
    ->where('answers.answer_active', '=', '1')
    ->selectRaw('answers.answer_content as answer_content,
                  answers.id as answer_id,
                  answers.created_at as created_at,
                  answers.created_at as answer_upvote,
                  answers.created_at as answer_downvote,
                  questions.id as question_id, 
                  questions.question_title as question_title, 
                  questions.question_slug as question_slug, 
                  users.id as user_id, 
                  users.name as user_name, 
                  users.user_slug as user_slug,
                  upvote_answers.upvote as upvote');

echo $yourQuery->toSql(); //generated sql query as string
//$yourQuery->get(); //for get data from db

Результат:

select answers.answer_content as answer_content, answers.id as answer_id, answers.created_at as created_at, answers.created_at as answer_upvote, answers.created_at as answer_downvote, questions.id as question_id, questions.question_title as question_title, questions.question_slug as question_slug, users.id as user_id, users.name as user_name, users.user_slug as user_slug, upvote_answers.upvote as upvote from answers inner join questions on questions.id = answers.question_id inner join users on users.id = answers.user_id left join upvote_answers on upvote_answers.answer_id = answers.id where questions.question_active = ? and answers.answer_active = ?

Если вам нужен upvote_answers.user_id = '2' в leftJoin, необходимо использовать предварительное левое соединение:

->leftJoin('upvote_answers', function($advancedLeftJoin){
    $advancedLeftJoin->on('users.id', '=', 'contacts.user_id')
        ->where('upvote_answers.user_id', '=', 2);
})

Наконец, ответ для вашего примера:

$yourQuery = \DB::table('answers')
    ->join('questions', 'questions.id', '=', 'answers.question_id')
    ->join('users', 'users.id', '=', 'answers.user_id')
    ->leftJoin('upvote_answers', function($advancedLeftJoin){
        $advancedLeftJoin->on('users.id', '=', 'contacts.user_id')
            ->where('upvote_answers.user_id', '=', 2);
    })
    ->where('questions.question_active', '=', '1')
    ->where('answers.answer_active', '=', '1')
    ->selectRaw('answers.answer_content as answer_content,
                  answers.id as answer_id,
                  answers.created_at as created_at,
                  answers.created_at as answer_upvote,
                  answers.created_at as answer_downvote,
                  questions.id as question_id, 
                  questions.question_title as question_title, 
                  questions.question_slug as question_slug, 
                  users.id as user_id, 
                  users.name as user_name, 
                  users.user_slug as user_slug,
                  upvote_answers.upvote as upvote');

echo $yourQuery->toSql(); //generated sql query as string
//dd($yourQuery->get()); //result as collection

Результат:

select answers.answer_content as answer_content, answers.id as answer_id, answers.created_at as created_at, answers.created_at as answer_upvote, answers.created_at as answer_downvote, questions.id as question_id, questions.question_title as question_title, questions.question_slug as question_slug, users.id as user_id, users.name as user_name, users.user_slug as user_slug, upvote_answers.upvote as upvote from answers inner join questions on questions.id = answers.question_id inner join users on users.id = answers.user_id left join upvote_answers on users.id = contacts.user_id and upvote_answers.user_id = ? where questions.question_active = ? and answers.answer_active = ?

Значение ? связывается после использования ->get()

Мой запрос отличается от вашего.

user9452884 10.03.2018 13:38
Ответ принят как подходящий

Используя построитель запросов, вы можете написать свой запрос как

DB::table('answers as a')
    ->join('questions as q', 'q.id', '=', 'a.question_id')
    ->join('users as u', 'u.id', '=', 'a.user_id')
    ->leftJoin('upvote_answers as ua', function ($join) {
        $join->on('ua.answer_id', '=', 'a.id')
             ->where('ua.user_id', '=', 2);
    })
    ->where('q.question_active', '=', 1)
    ->where('a.answer_active', '=', 1)
    ->select(DB::raw('a.answer_content as answer_content,a.id as answer_id,a.created_at as created_at,a.created_at as answer_upvote,a.created_at as answer_downvote,q.id as question_id, q.question_title as question_title, q.question_slug as question_slug, u.id as user_id, u.name as user_name, u.user_slug as user_slug,ua.upvote as upvote'))
    ->get();

Спасибо, это сработало, но мне пришлось написать «где» вместо «вкл». -where ('ua.user_id', '=', 2);

user9452884 10.03.2018 16:51

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