将原始 sql 查询转换为 laravel eloquent 查询
Translating Raw sql query to laravel eloquent query
我有一个工作正常的原始查询,但我无法将其转换为 laravel eloquent...
这是我的 tables :
用户 table
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->string('username', 30)->unique();
$table->string('email')->unique();
$table->string('password', 60);
$table->integer('role_id')->unsigned();
$table->boolean('seen')->default(false);
$table->boolean('valid')->default(false);
$table->boolean('confirmed')->default(false);
$table->string('confirmation_code')->nullable();
$table->timestamps();
$table->rememberToken();
});
客户table
Schema::create('clients', function(Blueprint $table)
{
$table->increments('id');
$table->integer('id_marchand')->unsigned()->index();
$table->foreign('id_marchand')->references('id')->on('users')->onDelete('cascade')->onUpdate('restrict');
$table->integer('id_client')->unsigned()->index();
$table->foreign('id_client')->references('id')->on('users')->onDelete('cascade')->onUpdate('restrict');
$table->timestamps();
});
雇员 table
Schema::create('employes', function(Blueprint $table)
{
$table->increments('id');
$table->integer('id_marchand')->unsigned()->index();
$table->foreign('id_marchand')->references('id')->on('users')->onDelete('cascade')->onUpdate('restrict');
$table->integer('id_employe')->unsigned()->index();
$table->foreign('id_employe')->references('id')->on('users')->onDelete('cascade')->onUpdate('restrict');
$table->timestamps();
});
用户模型
<?php namespace App\Models;
/**
* One to Many relation
*
* @return Illuminate\Database\Eloquent\Relations\hasMany
*/
public function employes()
{
return $this->hasMany('App\Models\Employe', 'id_marchand');
}
/**
* One to Many relation
*
* @return Illuminate\Database\Eloquent\Relations\hasMany
*/
public function clients()
{
return $this->hasMany('App\Models\Client', 'id_marchand');
}
客户端模型
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Client extends Model
{
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'clients';
/**
* One to Many relation
*
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo('App\Models\User');
}
}
用人模式
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Employe extends Model
{
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'employes';
/**
* One to Many relation
*
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo('App\Models\User');
}
}
我正在尝试翻译的原始查询:
SELECT users.*
FROM clients, users
WHERE clients.id_marchand = 8
AND users.id = clients.id_client
UNION
SELECT users.*
FROM employes, users
WHERE employes.id_marchand = 8
AND users.id = employes.id_employe
UNION
SELECT users.*
FROM users
WHERE users.id = 8
ORDER BY `seen` ASC, `created_at` DESC
LIMIT 25 OFFSET 0
我的问题是:
- 如果我尝试通过
DB::raw()
使用原始查询,它 returns
数组,然后我无法对结果进行分页或排序。
- 我无法从 Eloquent
中的多个 table 中找到执行 'select' 的方法
- 我不知道如何从数组中提取数据并获取集合
- 我仍然不确定我这样做是否正确。
那么有没有办法让它发挥作用?
编辑:
明确地说,我想要得到的是:
集合 用户,包含:
- 属于用户 8
的 'clients' 的用户
- 属于用户 8
的 'employes' 的用户
- 用户 8.
我可以在上面应用 ->oldest('seen')->latest()->paginate($n)
或类似的东西。
看起来您的员工模型设置正确,这应该使这相当简单...
我认为考虑您正在尝试做什么以及 Eloquent 如何帮助您做到这一点比简单地尝试将查询转换为使用查询生成器更容易。
$id = 8;
$users = App\User::whereHas('clients', function($q) use ($id) {
$q->where('id_marchand', $id);
})->orWhereHas('employes', function($q) use ($id) {
$q->where('id_marchand', $id);
})->orWhere('id', $id)
->orderBy('seen')
->oldest()
->get();
这将 return 一组 User
个模型。如果您想分页,只需将 get()
换成 paginate($numRecords)
,其中 $numRecords 是您希望每页显示的记录数。
然后使用该模型集合,您可以使用 foreach 循环输出每个用户的数据....
foreach ($users as $user) {
echo 'email: ' . $user->email;
}
编辑:我错了,我没有仔细看模型。因此,在您的查询中,您将分别按 id_client
和 id_employe
列加入客户和雇员表。因此,如果您修改 User
模型并将 employes
函数的 id_marchand
更改为 id_employe
,clients
函数的 id_client
,则此代码应该工作(或者至少对我有用)。
为了清楚起见,上面的代码生成了以下查询,因此您可以在进行任何更改之前亲自查看结果...
SELECT
*
FROM
`users`
WHERE EXISTS
(SELECT
*
FROM
`clients`
WHERE `clients`.`id_client` = `users`.`id`
AND `id_marchand` = '8')
OR EXISTS
(SELECT
*
FROM
`employes`
WHERE `employes`.`id_employe` = `users`.`id`
AND `id_marchand` = '8')
OR `id` = '8'
ORDER BY `seen` ASC,
`created_at` ASC
我有一个工作正常的原始查询,但我无法将其转换为 laravel eloquent...
这是我的 tables :
用户 table
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->string('username', 30)->unique();
$table->string('email')->unique();
$table->string('password', 60);
$table->integer('role_id')->unsigned();
$table->boolean('seen')->default(false);
$table->boolean('valid')->default(false);
$table->boolean('confirmed')->default(false);
$table->string('confirmation_code')->nullable();
$table->timestamps();
$table->rememberToken();
});
客户table
Schema::create('clients', function(Blueprint $table)
{
$table->increments('id');
$table->integer('id_marchand')->unsigned()->index();
$table->foreign('id_marchand')->references('id')->on('users')->onDelete('cascade')->onUpdate('restrict');
$table->integer('id_client')->unsigned()->index();
$table->foreign('id_client')->references('id')->on('users')->onDelete('cascade')->onUpdate('restrict');
$table->timestamps();
});
雇员 table
Schema::create('employes', function(Blueprint $table)
{
$table->increments('id');
$table->integer('id_marchand')->unsigned()->index();
$table->foreign('id_marchand')->references('id')->on('users')->onDelete('cascade')->onUpdate('restrict');
$table->integer('id_employe')->unsigned()->index();
$table->foreign('id_employe')->references('id')->on('users')->onDelete('cascade')->onUpdate('restrict');
$table->timestamps();
});
用户模型
<?php namespace App\Models;
/**
* One to Many relation
*
* @return Illuminate\Database\Eloquent\Relations\hasMany
*/
public function employes()
{
return $this->hasMany('App\Models\Employe', 'id_marchand');
}
/**
* One to Many relation
*
* @return Illuminate\Database\Eloquent\Relations\hasMany
*/
public function clients()
{
return $this->hasMany('App\Models\Client', 'id_marchand');
}
客户端模型
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Client extends Model
{
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'clients';
/**
* One to Many relation
*
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo('App\Models\User');
}
}
用人模式
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Employe extends Model
{
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'employes';
/**
* One to Many relation
*
* @return Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo('App\Models\User');
}
}
我正在尝试翻译的原始查询:
SELECT users.*
FROM clients, users
WHERE clients.id_marchand = 8
AND users.id = clients.id_client
UNION
SELECT users.*
FROM employes, users
WHERE employes.id_marchand = 8
AND users.id = employes.id_employe
UNION
SELECT users.*
FROM users
WHERE users.id = 8
ORDER BY `seen` ASC, `created_at` DESC
LIMIT 25 OFFSET 0
我的问题是:
- 如果我尝试通过
DB::raw()
使用原始查询,它 returns 数组,然后我无法对结果进行分页或排序。 - 我无法从 Eloquent 中的多个 table 中找到执行 'select' 的方法
- 我不知道如何从数组中提取数据并获取集合
- 我仍然不确定我这样做是否正确。
那么有没有办法让它发挥作用?
编辑:
明确地说,我想要得到的是:
集合 用户,包含:
- 属于用户 8 的 'clients' 的用户
- 属于用户 8 的 'employes' 的用户
- 用户 8.
我可以在上面应用 ->oldest('seen')->latest()->paginate($n)
或类似的东西。
看起来您的员工模型设置正确,这应该使这相当简单...
我认为考虑您正在尝试做什么以及 Eloquent 如何帮助您做到这一点比简单地尝试将查询转换为使用查询生成器更容易。
$id = 8;
$users = App\User::whereHas('clients', function($q) use ($id) {
$q->where('id_marchand', $id);
})->orWhereHas('employes', function($q) use ($id) {
$q->where('id_marchand', $id);
})->orWhere('id', $id)
->orderBy('seen')
->oldest()
->get();
这将 return 一组 User
个模型。如果您想分页,只需将 get()
换成 paginate($numRecords)
,其中 $numRecords 是您希望每页显示的记录数。
然后使用该模型集合,您可以使用 foreach 循环输出每个用户的数据....
foreach ($users as $user) {
echo 'email: ' . $user->email;
}
编辑:我错了,我没有仔细看模型。因此,在您的查询中,您将分别按 id_client
和 id_employe
列加入客户和雇员表。因此,如果您修改 User
模型并将 employes
函数的 id_marchand
更改为 id_employe
,clients
函数的 id_client
,则此代码应该工作(或者至少对我有用)。
为了清楚起见,上面的代码生成了以下查询,因此您可以在进行任何更改之前亲自查看结果...
SELECT
*
FROM
`users`
WHERE EXISTS
(SELECT
*
FROM
`clients`
WHERE `clients`.`id_client` = `users`.`id`
AND `id_marchand` = '8')
OR EXISTS
(SELECT
*
FROM
`employes`
WHERE `employes`.`id_employe` = `users`.`id`
AND `id_marchand` = '8')
OR `id` = '8'
ORDER BY `seen` ASC,
`created_at` ASC