Как преобразовать необработанный запрос MYSQL в построитель запросов Laravel 10 с использованием index(some_column)

Я хотел преобразовать свой Cakephp в Laravel 10.
Здесь, в Cakephp 2.x

$sql = [
    'fields' => [
        'Student.name',
        'Room.id'
    ],
    'joins' => [
        'use index(course)',
        [
            'table' => 'rooms',
            'alias' => 'Room use index(weekday, semester, year)',
            'type' => 'left',
            'conditions' => 'Student.course = Room.course'
        ]
    ],
    'conditions' => [
        'Student.course IN' => $courses,
        'Room.weekday' => $weekday,
        'Room.semester' => $semester,
        'Room.year' => $year,
    ]
];
$result = $this->Student->find('all', $sql);

тогда это теперь необработанный запрос.

"SELECT 
    Student.name, 
    Room.id 
FROM 
    students AS Student USE INDEX (course)
LEFT JOIN 
    rooms AS Room USE INDEX (weekday, semester, year)
ON 
    Student.course = Room.course 
WHERE 
    Room.weekday = '$day' 
    AND Room.semester = '$semester' 
    AND Room.year = '$year' 
    AND Student.course IN ($implodedCourse);"

После преобразования в Laravel 10 у меня возникла ошибка. Вот мой код.

$result = DB::table('students as Student use index(course)')
    ->select('Student.name', 'Room.id')
    ->join('rooms as Room use index(weekday, semester, year)', function($courseJoin){
    $courseJoin->on('Student.course', '=', 'Room.course'); })
    ->whereIn('Student.course', $courses)
    ->where('Room.weekday', $day)
    ->where('Room.semester', $semester)
    ->where('Room.year', $year);

Ошибка. Это указано.
Illuminate \ Database \ QueryException
SQLSTATE[HY000]: Общая ошибка: 1 нет такого столбца: Student.name

select "Student"."name", "Room"."id" from "students" as "Student use index(course)" inner join "rooms" as "Room use index(weekday, semester, year)" on "Student"."course" = "Room"."course" where "Student"."course" in (1, 3) and "Room"."weekday" = 3 and "Room"."semester" = 1 and "Room"."year" = 2024

Пожалуйста, помогите мне. Заранее спасибо.

Решено... Ссылка на запрос здесь

Я опубликовал свой ответ. Пожалуйста, проверьте и дайте мне знать.

Subha 14.06.2024 11:31
Стоит ли изучать 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-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
3
1
84
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я предполагаю, что две таблицы, упомянутые в запросе, правильно названы students и rooms.

Попробуй это.

$results = DB::table('students as Student')
    ->select('Student.name', 'Room.id')
    ->join('rooms as Room', 'Student.course', '=', 'Room.course')
    ->whereIn('Student.course', $courses)
    ->where('Room.weekday', $day)
    ->where('Room.semester', $semester)
    ->where('Room.year', $year)
    ->get();

В предложении whereIn вы также можете указать данные вместо $courses в виде массива, например: -> [1,2,3].

реализовать это. Я думаю, это сработает. Если нет, дайте мне знать.

N:B: - не забудьте импортировать фасад DB в начало скрипта, используя use Illuminate\Support\Facades\DB;.

Если вам нужно использовать index(some_columns) в запросе, попробуйте это.

$result = DB::table(DB::raw('students as Student USE INDEX(course)'))
    ->select('Student.name', 'Room.id')
    ->join(DB::raw('rooms as Room USE INDEX(weekday, semester, year)'), function($courseJoin) {
        $courseJoin->on('Student.course', '=', 'Room.course');
    })
    ->whereIn('Student.course', $courses)
    ->where('Room.weekday', $day)
    ->where('Room.semester', $semester)
    ->where('Room.year', $year)
    ->get();

Проверьте также это решение и дайте мне знать.

Я попробовал вашу реализацию, сэр, это хорошо, вот журнал sql, когда я использую ->toSql(), выберите "Студент"."имя", "Комната"."id" из "студентов" как "Студент" внутреннее соединение "комнаты" как "Комната" на "Студент"."курс" = "Комната"."курс" где "Студент"."курс" в (?, ?) и "Комната"."будний день" = ? и «Комната».»семестр» = ? и «Комната». «Год» = ? Однако необходимо использовать индекс (some_columns) после псевдонима или «AS NewTableName».

トロイ 14.06.2024 12:07

@トロイ,я отредактировал свой ответ для index(some_columns) . Пожалуйста, проверьте и дайте мне знать.

Subha 14.06.2024 12:12

привет, сэр @Subha, я попробовал ваше решение, но все равно получаю ошибку. Illuminate\ Database\ QueryException SQLSTATE[HY000]: Общая ошибка: 1 рядом с «USE»: синтаксическая ошибка select "Student"."name", "Room"."id" from students as Student USE INDEX(course) inner join rooms as Room USE INDEX(weekday, semester, year) on "Student"."course" = "Room"."course" where "Student"."course" in (1, 3) and "Room"."weekday" = 3 and "Room"."semester" = 1 and "Room"."year" = 2024

トロイ 18.06.2024 03:58

@トロイ, попробуйте это DB::raw('students USE INDEX (course) as Student') и (DB::raw('rooms USE INDEX (weekday, semester, year) as Room'). используйте это в существующем запросе, оставив оставшийся запрос таким же, и дайте мне знать. должно работать, но не знаю, почему это не так. какая-то проблема с USE INDEX.

Subha 18.06.2024 07:44

Спасибо, сэр @Subha, я правильно понял журналы запросов. select Student.name, Room.id from students as Student use index (course) left join rooms as Room USE INDEX (weekday, semester, year) on Student.course = Room.course where Student.course in (1, 3) and Room.weekday = 2 and Room.semester = 2 and Room.year = 2024 USE INDEX появляется, когда я использовал базу данных MySQL, однако его нельзя отобразить в sqlite... Очень признателен, сэр.

トロイ 18.06.2024 09:11

@トロイ, я рад помочь тебе. Пожалуйста, прими мой ответ.

Subha 18.06.2024 09:13

@トロイ, я только что проверил ответ @Arun AS. Он более подробный и краткий. Спасибо, что поддержали мой ответ. Но я думаю, вам следует принять Arun's ответ вместо моего.

Subha 18.06.2024 09:27
Ответ принят как подходящий

Основная проблема здесь в том, что Laravel не смог понять use index() в вашем коде.

Для Laravel 9 и выше в Illuminate\Database\Query\Builder добавлено 3 новых метода useIndex , ForceIndex и ignoreIndex, которые позволяют добавлять подсказки индекса.

$result = DB::table('students as Student')
    ->useIndex('course')
    ->select('Student.name', 'Room.id')
    ->leftJoin(DB::raw('rooms as `Room` use index(weekday, semester, year)'), function ($courseJoin) {
        $courseJoin->on('Student.course', '=', 'Room.course');;
    })
    ->whereIn('Student.course', $courses)
    ->where('Room.weekday', $day)
    ->where('Room.semester', $semester)
    ->where('Room.year', $year)
    ->get();

Однако вам нужно будет использовать DB::raw() для добавления подсказок индекса в соединениях.

Для Laravel < 9 используйте DB::raw() в методе table().

$result = DB::table(DB::raw('students as `Student` use INDEX(course)'))
    ->select('Student.name', 'Room.id')
    ->leftJoin(DB::raw('rooms as `Room` use index(weekday, semester, year)'), function ($courseJoin) {
        $courseJoin->on('Student.course', '=', 'Room.course');;
    })
    ->whereIn('Student.course', [1, 2])
    ->where('Room.weekday', 2)
    ->where('Room.semester', 3)
    ->where('Room.year', 2024)
    ->get();

Я попробую это, когда вернусь на работу. Я взял отпуск в понедельник

トロイ 14.06.2024 15:16

Здравствуйте, сэр @arun-a-s. Я попробовал ваше решение, но получил сообщение об ошибке: Illuminate\ Database\ QueryExceptionSQLSTATE[HY000]: General error: 1 near "use": syntax errorselect "Student"."name", "Room"."id" from students as Student use INDEX(course) left join rooms as Room use index(weekday, semester, year) on "Student"."course" = "Room"."course" where "Student"."course" in (1, 3) and "Room"."weekday" = 3 and "Room"."semester" = 1 and "Room"."year" = 2024

トロイ 18.06.2024 04:07
$result = DB::table('students as Student') ->useIndex('course') ->select('Student.name', 'Room.id') ->leftJoin(DB::raw('rooms as Room USE INDEX (weekday, semester, year)'), function($courseJoin) { $courseJoin->on('Student.course', '=', 'Room.course'); }) ->whereIn('Student.course', $courses) ->where('Room.weekday', $day) ->where('Room.semester', $semester) ->where('Room.year', $year) ->toRawSql(); спасибо, сэр...
トロイ 18.06.2024 09:14

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