Laravel eloquent 具有多个内部联接

Laravel eloquent with multiple inner joins

我目前正在执行原始 sql 查询,但这会导致关系和模型启动方法出现问题。

是否可以通过关系使用 laravel eloquent 模型执行以下 SQL 查询?请注意,所有数据库表都定义了 FK,并且关系为 HasOne 或 HasMany 关系。

    $timeBreakDown = DB::select(
        "SELECT
                Entries.`task_id`,
                Entries.`opportunity_id`,
                SUM(Entries.`total_duration`) as 'duration',
                Class.`class` as 'class',
                Subclass.`sub_class` as 'subclass'
            from entries Entries
                INNER JOIN `tasks` Task
                    ON task_id = Task.id
                INNER JOIN `task_class` Class
                    ON Task.`class_id` = Class.`id`
                INNER JOIN `task_subclasses` Subclass
                    ON Task.`subclass_id` = Subclass.`id`
                WHERE Entries.`opportunity_id` = '".$opportunity->id."'
                GROUP BY Entries.`task_id`"
    );

模特是

Entries
Tasks
Class
Subclass

我必须如何构建我的模型关系才能处理上述 sql 查询?

是的,您可以使用 Eloquent 我将与您分享一个示例 我无法阅读您的 Mess Query 对此感到抱歉,但我会建议您这样做

Entries::with(['Tasks','Class','Subclass'])->get();

由此,您将获得此数组中的所有对象

随便说说

class 与另一个模型有关系,但与条目没有关系 table 然后 Eloquent 是这样的

Entries::with(['Tasks','Class.Subclass'])->get();

希望对您有所帮助

如果你能发布你的模型,那对我们来说会更容易。但这是我从上面的原始查询中得到的。

$timeBreakDown = Entries::where('opportunity_id',$opportunity->id)->load('Tasks','Class.SubClass')->get();

您应该了解 Laravel Eloquent 和关系。简单介绍一下,Waleed 使用的 load 和 with 之间的区别是: load用于延迟加载关系数据,with用于预加载。

Eager loading is all the data gets load as soon as the Eloquent queries the data while lazy loading loads the data when it is required.

可能是这样的:

$timeBreakDown = Entries::select('entries.task_id, entries.opportunity_id', DB:raw('SUM(Entries.total_duration) as duration), task_class.class, task_subclasses.sub_class as subclass)
join('tasks', [['tasks.id', 'entries.task_id']])
join('task_class', [['task_class.id', 'entries.class_id']])
join('task_subclasses', [['task_subclasses.id', 'entries.subclass_id']])
->where('entries.opportunity_id', $opportunity->id)
->groupBy('entries.task_id')
->get();

试试这个查询:

$timeBreakDown = Entries::join('tasks', 'tasks.id', '=', 'entries.task_id')
            ->join('class', 'class.id', '=', 'entries.class_id')
            ->join('subclass', 'subclass.id', '=', 'entries.subclass_id')
            ->select(
                'entries.task_id',
                'entries.opportunity_id',
                \DB::raw('SUM(entries.total_duration) as duration'),
                'class.class',
                'subclass.sub_class as subclass')
            ->where('entries.opportunity_id', $opportunity->id)
            ->groupBy('entries.task_id')
            ->get();

并尝试 dd($timeBreakDown->toSql()); 与您的原始 SQL 查询相匹配。

来自官方文档。 您可以通过将 tasks 方法添加到 Entries 模型来使用基本数据库关系类型定义关系。 tasks 方法应该调用 hasOne 方法和 return 它的结果。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Entries extends Model
{
    /**
     * Get the phone associated with the user.
     */
    public function task()
    {
        return $this->hasOne(Tasks::class);
    }
}

反过来,Tasks 模型将有一个输入方法,我们可以使用该方法使用 belongsTo 方法确定 hasOne 关系的逆关系:

<?php
    
  namespace App\Models;
   
  use Illuminate\Database\Eloquent\Model;
    
  class Tasks extends Model
  {
      /**
       * Get the user that owns the phone.
       */
      public function entry()
      {
          return $this->belongsTo(Entries::class);
      }
  }

您只需像这样设置关系:

我假设 Class 会有 subClass 并且 Class 也会有 Tasks 而那些 Tasks 会有 Entries.

你也没有User模型吗?

Class 型号

class Class extends Model
{ 

  protected $with = ['entries', 'subclass', 'task'];

  public function entries()
  {
      return $this->hasManyThrough(\App\Models\Entries::class, \App\Models\Task::class);
  }

  public function subClass()
  {
      return $this->hasOne(\App\Models\subClass::class);
  }

  public function tasks()
  {
    return $this->hasMany(\App\Models\Task::class);
  }
}

入门型号

class Entry extends Model
{ 

  protected $with = ['task'];

  public function task()
  {
    return $this->belongsTo(Task::class);
  }
}

子Class型号

class SubClass extends Model
{ 

  protected $with = ['class'];

  public function class()
  {
    return $this->belongsTo(\App\Models\Class::class);
  }
}

任务模型

class Task extends Model
{ 

  protected $with = ['entries', 'class'];

  public function entries()
  {
      return $this->hasMany(\App\Models\Class::class);
  }

  public function class()
  {
    return $this->hasMany(\App\Models\Task::class);
  }
}

完成所有这些设置后,您应该可以在堆栈中的任何位置来回执行类似的操作:

$entry = Entry::findOrFail('id');
$entry->task->class->subClass->name;

$class = Class::findOrFail($class->id);
$subclass_name = $class->subclass->name;
$entries = $class->tasks->entries;

您可以这样写一个查询:
请根据您的数据库检查 table 个名称

DB:: table('table name')->join('tasks','task_id','=','tasks.id')
->join('task_class', 'tasks.subclass_id','=','task_class.id')
->join('task_subclasses','tasks.subclass_id','=', 'task_subclasses.id')
->selectRaw('entries.task_id,
            task_subclasses.opportunity_id,
            SUM(entries.total_duration) as duration,
            task_class.class as class,
            task_subclasses.sub_class as subclass') 
->where(['entries.opportunity_id'=>$opportunity->id])
->groupBy('enteries.task_id')->get();

Models\Entries.php

<?php

namespace App\Models;


use Illuminate\Database\Eloquent\Model;

class Entries extends Model
{
    public function Tasks(){
        return $this->hasOne(Tasks::class);
    }
    public function Class(){
        return $this->hasMany(Classes::class);
    }
    public function SubClasses(){
        return $this->hasOne(SubClasses::class);
    }
}

Models\Tasks.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Tasks extends Model
{
    public function Entries(){
        return $this->belongsTo(Entries::class, "id", "task_id");
    }
}

Models\Classes.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Classes extends Model
{
    public function Entries(){
        return $this->belongsTo(Entries::class, "class_id", "id");
    }
}

Models\Subclasses.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class SubClasses extends Model
{
    public function Entries(){
        
        return $this->belongsTo(Entries::class, "id", "subclass_id");
        
    }
}

查询:

Entries::with([
        "Tasks",
        "Classes",
        "SubClasses"
    ])
    ->where("opportunity_id", $opportunity->id)
    ->groupBy("task_id")
    ->get();