[英]laravel query builder: join dependent on primary content
I'm using luman and Database Query Builder to fetch full user info from database. 我正在使用luman和Database Query Builder从数据库中获取完整的用户信息。
First, Please Take a lock at my database structure: I have a table called users
and a series of other tables that are related to user groups (Ex: secretaries
, patients
, doctors
and admins
) which stores additional information about the users. 首先,请锁定我的数据库结构:我有一个名为
users
的表以及与用户组(例如: secretaries
, patients
, doctors
和admins
)相关的一系列其他表,这些表存储有关用户的其他信息。
Also To determine user access, I have a level
column on user
table which can have one of this value as enum: 'admin', 'doctor', 'secretary', 'patient'
. 另外,为了确定用户访问权限,我在
user
表上有一个level
列,该列可以具有以下值之一作为枚举: 'admin', 'doctor', 'secretary', 'patient'
。
So, I want to get this information using one query by join
and select
. 因此,我想通过
join
和select
使用一个查询来获取此信息。
My training code is something like this: 我的训练代码是这样的:
$userInfo = User::where("userID", $userID)
->limit(1)
->join('[GROUP_TABLE_NAME]', function ($join) {
$join->on('user.userID', '=', '[GROUP_TABLE_NAME]' .'.'.
'[GROUP_NAME]' . 'ID');
})
->get();
The GROUP_NAME
comes from level
column on user
table and the GROUP_TABLE_NAME
can be built based on the GROUP_NAME
value(Ex: ['secretary' => 'secretaries' , 'patient' => 'patients' , ...]
). GROUP_NAME
来自user
表的level
列,并且GROUP_TABLE_NAME
可以基于GROUP_NAME
值构建(例如: ['secretary' => 'secretaries' , 'patient' => 'patients' , ...]
GROUP_TABLE_NAME
['secretary' => 'secretaries' , 'patient' => 'patients' , ...]
GROUP_TABLE_NAME
['secretary' => 'secretaries' , 'patient' => 'patients' , ...]
)。
Any idea to handle the join structure using laravel query builder? 有什么想法使用laravel查询构建器来处理联接结构吗?
First you should be aware of the fact that this code architecture is not convenient and not easy to understand for other developers. 首先,您应该意识到以下事实:该代码体系结构对其他开发人员而言并不方便,也不容易理解。
SQL You can achieve your goal by using union
and join
. SQL您可以通过使用
union
和join
来实现您的目标。
Just convert this query for laravel builder or use it directly with DB::statement
: select users.*, infos.info from users left join (( select secretaries.* from secretaries ) UNION (select doctors.* from doctors)) infos ON users.id = infos.user_id where users.id=?
只需将查询转换为laravel生成器或直接将其与
DB::statement
一起使用即可: select users.*, infos.info from users left join (( select secretaries.* from secretaries ) UNION (select doctors.* from doctors)) infos ON users.id = infos.user_id where users.id=?
. 。
But 但
The easiest way to do it is to fetch info in two queries, both indexed and fast: user from users
by primary key and then info by indexed field user_id
in it. 最简单的方法是在两个查询中获取信息,这两个查询都是索引的和快速的:通过主键从用户获取
users
信息,然后通过其中的索引字段user_id
获取信息。 Create Doctorinfo
, Admininfo
models and correspondent migrations. 创建
Doctorinfo
, Admininfo
模型和相应的迁移。 So user class can be smth like this: 所以用户类可以像这样:
public function getInfo() {
switch($this->level) {
'doctor':
return $this->doctorinfo;
...
}
}
private function doctorinfo() {
$this->hasOne('App\Doctorinfo');
}
Builder 建造者
You can use left join to join all sub tables as well. 您也可以使用左联接来联接所有子表。 The following builder selects
info
column. 以下构建器选择
info
列。
User::where("userID", $userID)->limit(1)
->leftJoin('patients', 'users.id', '=', 'patients.user_id')
->leftJoin('doctors', 'users.id', '=', 'doctors.user_id')
->leftJoin('admins', 'users.id', '=', 'admins.user_id')
->select('users.*', DB::raw('IF(users.level="admin", admins.info, (IF users.level="doctors", doctors.info, patients.info))'))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.