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();
我目前正在执行原始 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();