【问题标题】:Translating Raw sql query to laravel eloquent query将原始 sql 查询转换为 laravel 雄辩的查询
【发布时间】:2017-01-05 14:13:05
【问题描述】:

我有一个可以正常工作的原始查询,但我无法将它翻译成 laravel eloquent...

这是我的桌子:

用户

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();
    });

客户

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();

    });

雇员

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

我的问题是:

  1. 如果我尝试通过DB::raw() 使用原始查询来执行此操作,它会返回一个 数组,然后我无法对结果进行分页或排序。
  2. 我找不到从 Eloquent 中的多个表中进行“选择”的方法
  3. 不知道如何从数组中提取数据并得到一个Collection
  4. 我仍然不确定我是否做得对。

那么有没有其他方法可以让它发挥作用?


编辑:

要清楚,我想要得到的是:

用户集合,包含:

  • 是用户 8 的“客户”的用户
  • 是用户 8 的“雇员”的用户
  • 用户 8。

我可以在上面申请 -&gt;oldest('seen')-&gt;latest()-&gt;paginate($n) 或类似的东西。

【问题讨论】:

    标签: php mysql laravel eloquent laravel-query-builder


    【解决方案1】:

    看起来您的员工模型设置正确,这应该会变得相当简单...

    我认为与简单地尝试将查询转换为使用查询构建器相比,思考您正在尝试做什么以及 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();
    

    这将返回User 模型的集合。如果您想分页,只需将 get() 替换为 paginate($numRecords),其中 $numRecords 是您希望每页的记录数。

    然后使用该模型集合,您可以使用 foreach 循环来输出每个用户的数据....

    foreach ($users as $user) {
        echo 'email: ' . $user->email;
    }
    

    编辑:我错了,我没有仔细观察模型。因此,在您的查询中,您将分别通过 id_clientid_employe 列加入客户和雇员表。因此,如果您修改User 模型并将id_marchand 更改为id_employe 用于employes 函数,将id_client 用于clients 函数,此代码应该可以工作(或者至少它对我有用)。

    为了澄清起见,上面的代码会生成以下查询,因此您可以在进行任何更改之前自己查看结果...

    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 
    

    【讨论】:

    • 感谢您的回答,但这不是我要问的。我会进入一个排序的用户集合:作为用户 8 的客户的所有用户,以及作为用户 8 的雇员的所有用户,以及用户 8 本人......
    • 我会用一些测试数据设置表格,看看问题出在哪里。
    • 哈利路亚!我已经疯了两个星期了,我已经尝试了所有可能的查询......谢谢!
    猜你喜欢
    • 2016-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-06
    • 2018-01-31
    • 2020-08-06
    • 2019-02-03
    • 1970-01-01
    相关资源
    最近更新 更多