在Laravel Orm代码中使用RAW在Laravel Orm代码中转动我的RAW SQL代码

发布于 2025-01-21 22:28:50 字数 4694 浏览 4 评论 0原文

我有一些复杂的SQL查询,需要在Laravel Web应用程序上使用它才能过滤一些数据。

经过一番反复试验,我弄清楚了我的SQL查询应该看起来如何(phpmyadmin中的结果很好)。

但是现在我在Laravel中使用它时会遇到一些错误。我知道为什么,但是我不知道我应该修复它。

因此,这是我用于过滤的文件:

<?php

namespace App\Filters;

use Illuminate\Database\Eloquent\Builder;
use DB;

use App\Student;


/**
 * Class DepartamentFilter
 * @package App\Filters
 */
class DoctoranziFilter extends Filter
{
    /**
     * @param Builder $query
     * @return mixed
     */
    public function apply($query)
    {

        if ($this->request->exists('filters')) {

            $name = $this->request->get('nume');
            if ($name !== null) {
                $query = $query->where('nume', 'like', '%' . $name . '%');
            }

            $an_inmatriculare = $this->request->get('an_inmatriculare');
            if ($an_inmatriculare !== null) {
                $query = $query->where('an_inmatriculare', 'like', '%' . $an_inmatriculare . '%');
            }

            $domeniu_doctorat_id = $this->request->get('domeniu_doctorat_id');
            if ($domeniu_doctorat_id !== "0") {
                $query = $query->where('domeniu_doctorat_id', '=', $domeniu_doctorat_id);
            }

            $conducator_doctorat_id = $this->request->get('conducator_doctorat_id');
            if ($conducator_doctorat_id !== "0") {
                $query = $query->where('conducator_doctorat_id', '=', $conducator_doctorat_id);
            }

            $status = $this->request->get('status');
            if ($status !== "0") {
                $query = DB::Select("select * from `students`
                where (
                    select status_student.id from `status_student` 
                WHERE
                status_student.id = (SELECT MAX(status_student.id) from `status_student`
                WHERE 
                status_student.student_id = students.id)
                AND
                status_student.status_id = 6
                ) 
                IS NOT NULL;");
            } 

            $stare_stagiu = $this->request->get('stare-stagiu');
            if ($stare_stagiu !== "0") {
                $query = Student::whereHas('statusuri', function($q) use ($stare_stagiu) {
                    $q->where('stare_stagiu_id', '=', $stare_stagiu);
                });
            }        

            $forma_admitere_id = $this->request->get('forma_admitere_id');
            if ($forma_admitere_id !== "0") {
                $query = $query->where('forma_admitere_id', '=', $forma_admitere_id);
            }

            $campOrdonare = $this->request->get('ordonare-dupa-camp');
            if($campOrdonare !== "0") {
                $ordine = $this->request->get('ordine');
                if($campOrdonare === "1")
                {
                    $query = $query->orderBy('nume', $ordine);
                }
                else
                {
                    $query = $query->orderBy('an_inmatriculare', $ordine);
                }
            }

            return $query;

        } else {

            $query = $query->where('respins', '=', 0);

            return $query;
        }
    }
}

有问题的部分是$状态的查询。

从所有其他$查询变量中,我链接一些SQL。 (例如,一个地方,订单等) 对于$状态变量,我不这样做,我已经使用了RAW SQL,这就是为什么它无法正常工作的原因。

那么,我该怎么办?有什么办法可以以某种方式将DB ::选择为QueryBuilder? (老实说,我不这么认为)

我认为我需要将这种原始SQL变成雄辩,但我很难做到这一点。我已经尝试了很长时间了,但我做不到。

我有3个表格查询需要操作的3个表:

STUDENTS     STATUS        STATUS_STUDENT
ID           ID            students.id
                           status.id

我将从代码中解释查询:

"select * from `students`
                where (
                    select status_student.id from `status_student` 
                WHERE
                status_student.id = (SELECT MAX(status_student.id) from `status_student`
                WHERE 
                status_student.student_id = students.id)
                AND
                status_student.status_id = 6
                ) 
                IS NOT NULL;"

6 would be the user input, in this case it is hardcoded for testing purposes

学生可以具有多个状态 - 但是主动的是他的最后一个。然后,我想检查学生的活动状态ID是否与用户输入相等(在上面的6个情况下,它是用于测试的硬编码)。如果是这样,请退还符合条件的学生。如果没有,请不要退货。 (例如,例如,如果学生具有该状态,但不是活跃的状态,请不要返回任何东西),

这是学生与代码状态之间的关系:

public function statusuri()
{
        return $this->belongsToMany(Status::class, 'status_student')
            ->withPivot('id', 'status_id', 'stare_stagiu_id')
            ->withTimestamps();
}

那么,我该如何使此查询在我的上下文中起作用? (在原始SQL时,将其与QueryBuilders链接在一起)。如果我是对的,我需要将其变成雄辩的代码,有人可以帮我做吗?我自己无法弄清楚。

谢谢。

I have a bit of a complicated SQL query that I need to have it on my Laravel web app in order to filter some data.

After a bit of trial and error, I figured out how my SQL query should look (the results are fine in PHPmyadmin).

But now I get some errors when using it in Laravel. I know why, but I don't know should I fix it.

So here's the file that I'm using for filtering:

<?php

namespace App\Filters;

use Illuminate\Database\Eloquent\Builder;
use DB;

use App\Student;


/**
 * Class DepartamentFilter
 * @package App\Filters
 */
class DoctoranziFilter extends Filter
{
    /**
     * @param Builder $query
     * @return mixed
     */
    public function apply($query)
    {

        if ($this->request->exists('filters')) {

            $name = $this->request->get('nume');
            if ($name !== null) {
                $query = $query->where('nume', 'like', '%' . $name . '%');
            }

            $an_inmatriculare = $this->request->get('an_inmatriculare');
            if ($an_inmatriculare !== null) {
                $query = $query->where('an_inmatriculare', 'like', '%' . $an_inmatriculare . '%');
            }

            $domeniu_doctorat_id = $this->request->get('domeniu_doctorat_id');
            if ($domeniu_doctorat_id !== "0") {
                $query = $query->where('domeniu_doctorat_id', '=', $domeniu_doctorat_id);
            }

            $conducator_doctorat_id = $this->request->get('conducator_doctorat_id');
            if ($conducator_doctorat_id !== "0") {
                $query = $query->where('conducator_doctorat_id', '=', $conducator_doctorat_id);
            }

            $status = $this->request->get('status');
            if ($status !== "0") {
                $query = DB::Select("select * from `students`
                where (
                    select status_student.id from `status_student` 
                WHERE
                status_student.id = (SELECT MAX(status_student.id) from `status_student`
                WHERE 
                status_student.student_id = students.id)
                AND
                status_student.status_id = 6
                ) 
                IS NOT NULL;");
            } 

            $stare_stagiu = $this->request->get('stare-stagiu');
            if ($stare_stagiu !== "0") {
                $query = Student::whereHas('statusuri', function($q) use ($stare_stagiu) {
                    $q->where('stare_stagiu_id', '=', $stare_stagiu);
                });
            }        

            $forma_admitere_id = $this->request->get('forma_admitere_id');
            if ($forma_admitere_id !== "0") {
                $query = $query->where('forma_admitere_id', '=', $forma_admitere_id);
            }

            $campOrdonare = $this->request->get('ordonare-dupa-camp');
            if($campOrdonare !== "0") {
                $ordine = $this->request->get('ordine');
                if($campOrdonare === "1")
                {
                    $query = $query->orderBy('nume', $ordine);
                }
                else
                {
                    $query = $query->orderBy('an_inmatriculare', $ordine);
                }
            }

            return $query;

        } else {

            $query = $query->where('respins', '=', 0);

            return $query;
        }
    }
}

The problematic part is the query on $status.

From all the others $query variable, I chain a bit of SQL. (like, a where, an order by, etc)
For the $status variable, I don't do that, I'm using raw SQL already and that is why it is not working well.

So, what should I do? Is there any way to somehow turn that DB::Select into a QueryBuilder? (I don't think so, to be honest)

I think that I need to turn that raw SQL into Eloquent but I'm having trouble doing that. I've been trying that for a long time and I couldn't do it.

I have 3 tables that this $status query needs to operate on:

STUDENTS     STATUS        STATUS_STUDENT
ID           ID            students.id
                           status.id

I will explain the query from the code:

"select * from `students`
                where (
                    select status_student.id from `status_student` 
                WHERE
                status_student.id = (SELECT MAX(status_student.id) from `status_student`
                WHERE 
                status_student.student_id = students.id)
                AND
                status_student.status_id = 6
                ) 
                IS NOT NULL;"

6 would be the user input, in this case it is hardcoded for testing purposes

A student can have multiple status - but the active one is the last one that he has. Then I want to check if the student's active status id is equal to the user input (in the case above with 6, it was hardcoded for my tests). If so, return the students which match the criteria. If not, don't return anything. (so, for example, if the student has that status but it is not the active one, don't return anything)

Here's the relationship between Student and Status in code:

public function statusuri()
{
        return $this->belongsToMany(Status::class, 'status_student')
            ->withPivot('id', 'status_id', 'stare_stagiu_id')
            ->withTimestamps();
}

So, how can I make this query work in my context? (having it chained with QueryBuilders while it being raw SQL). If I am right and I need to turn it into Eloquent code, can anybody help me do it? I couldn't figure it out myself.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文