简体   繁体   English

到 Laravel 查询构建器的 SQL 查询

[英]SQL query to Laravel query builder

I have 2 tables我有2张桌子

risks

risk_id    name    area_id
1          a       1
2          b       1

risk_areas

id         name    parent_id
1          a       0
2          b       1
3          c       1
4          d       2

This is my sql query:这是我的 sql 查询:

SELECT * FROM `risks` WHERE (`register_id` = 29 AND `area_id` = 1) 
OR (`area_id` IN (SELECT id FROM risk_areas WHERE parent_id = 1) AND `register_id` = 29 ) 
OR (`area_id` IN (SELECT id FROM risk_areas WHERE parent_id IN (SELECT id FROM risk_areas WHERE parent_id = 1)) AND `register_id` = 29 ) 

When run in phpMyAdmin the query works as expected.在 phpMyAdmin 中运行时,查询按预期工作。

I've been trying to implement it into Laravel using the query builder.我一直在尝试使用查询构建器将它实现到 Laravel 中。 It fetches a risk from a certain register (I've used 29 for an example) and also finds all of its children risks (there can only be up to 3 generations eg parent->child->child)它从某个寄存器中获取风险(我以 29 为例)并且还发现了它的所有子级风险(最多只能有 3 代,例如 parent->child->child)

I intially tried this:我最初尝试过这个:

$query-> raw("
    SELECT * FROM `risks` WHERE (`register_id` = " . $q['register_id'] . "  AND `area_id` = ".$q['area_id'].") 
    OR (`area_id` IN (SELECT id FROM risk_areas WHERE parent_id = ".$q['area_id'].") AND `register_id` = " . $q['register_id'] . " ) 
    OR (`area_id` IN (SELECT id FROM risk_areas WHERE parent_id IN (SELECT id FROM risk_areas WHERE parent_id = ".$q['area_id'].")) AND `register_id` =  " . $q['register_id'] . " ) 
");

$q['register_id'] fetches the register_id and $q['area_id'] fetches the area_id correctly. $q['register_id']获取register_id$q['area_id']正确获取area_id

Since that didn't work (it just outputted the parents and even the ones with the same area_id but different register ids) I tried this:由于这不起作用(它只是输出了父级,甚至输出了具有相同 area_id 但寄存器 ID 不同的父级),我尝试了以下操作:

$query
    ->where('area_id', $q['area_id'])
    ->orWhere('area_id','IN',  function ($query) use($q) {
        $query->where('parent_id',$q['area_id'])
            ->where('register_id',$q['register_id']);
    })
    ->orWhere('area_id','IN',  function ($query) use($q) {
        $query->where('parent_id','IN', function ($query) use($q) {
            $query->where('parent_id',$q['area_id']);
        })
        ->where('register_id',$q['register_id']);
    })
    ->where('register_id',$q['register_id']);

But this did the same as the first.但这与第一个相同。 My 3rd attempt:我的第三次尝试:

$query
    ->where('area_id', $q['area_id'])
    ->orWhere('area_id','IN',  function ($query) use($q) {
        $query->DB::table('risk_areas')
            ->select(DB::raw('id'))
            ->where('parent_id',$q['area_id'])
            ->where('register_id',$q['register_id']);
    })
    ->orWhere('area_id','IN',  function ($query) use($q) {
        $query->DB::table('risk_areas')
            ->select(DB::raw('id'))
            ->where('parent_id','IN', function ($query) use($q) {
                $query->DB::table('risk_areas')
                    ->select(DB::raw('id'))
                    ->where('parent_id',$q['area_id']);
            })
            ->where('register_id',$q['register_id']);
    })
    ->where('register_id',$q['register_id'])->get();

But this does the same as the first.但这与第一个相同。 How can I replicate the sql query?如何复制sql查询?

EDIT:编辑:

Each register has its own register_id (this is only used to tighten the search).每个寄存器都有自己的 register_id(这仅用于加强搜索)。

Each register contains many risks.每个登记册都包含许多风险。

Each risk can only have one risk_area.每个风险只能有一个 risk_area。

I have got the same results each time, whether feeding a raw sql query or using the query builder.无论是提供原始 sql 查询还是使用查询构建器,我每次都得到相同的结果。

The only time where I got different(and correct) results was when I fed the query into phpmyadmin (hence why I want to replicate the working query in my code).我得到不同(和正确)结果的唯一一次是当我将查询输入 phpmyadmin 时(因此我想在我的代码中复制工作查询)。

The variables all have correct values as I have checked using dd().正如我使用 dd() 检查过的那样,这些变量都具有正确的值。

I think the reason is that my syntax on the query builder is incorrect, which is why I ask how to convert my sql query into the laravel query builder.我认为原因是我在查询构建器上的语法不正确,这就是为什么我问如何将我的 sql 查询转换为 Laravel 查询构建器。

EDIT 2:编辑2:

The raw query outputs all the risks for a specific register (all the risks displayed belong to that register).原始查询输出特定寄存器的所有风险(显示的所有风险都属于该寄存器)。 When I hard code values into the raw query, I get the same result (whatever register_id/area_id combo I put in, I will get all the results for that register as this is the default view for the page.).当我将值硬编码到原始查询中时,我得到相同的结果(无论我输入什么 register_id/area_id 组合,我都会得到该寄存器的所有结果,因为这是页面的默认视图。)。 This makes me think that maybe the raw query isn't being processed properly?这让我觉得原始查询可能没有得到正确处理?

To translate WHERE IN (SELECT ... ) , you need to use whereIn .要翻译WHERE IN (SELECT ... ) ,您需要使用whereIn

Also, trying to use DB::table() inside a subquery won't yield the result you expect.此外,尝试在子查询中使用DB::table()不会产生您期望的结果。

This:这个:

 .., function ($query) use($q) { $query->DB::table('risk_areas') ... })

Should be:应该:

 .., function ($query) use($q) { $query->from('risk_areas') ... })

The translated query should then, end up like this:翻译后的查询应该像这样结束:

DB::table('risks')
    ->where(function ($query) {
        $query->where('register_id', 29)
              ->where('area_id', 1);
    })
    ->orWhere(function ($query) {
        $query->whereIn('area_id', function ($sQuery) {
                  $sQuery->select('id')
                         ->from('risk_areas')
                         ->where('parent_id', 1);
              })
              ->where('register_id', 29);
    })
    ->orWhere(function ($query) {
        $query->whereIn('area_id', function ($sQuery) {
                  $sQuery->select('id')
                         ->from('risk_areas')
                         ->whereIn('parent_id', function ($sQuery2) {
                             $sQuery2->select('id')
                                     ->from('risk_areas')
                                     ->where('parent_id', 1);
                         });
              })
              ->where('register_id', 29);
    })
    ->get();
   

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM