【问题标题】:Laravel Eloquent left join queryLaravel Eloquent 左连接查询
【发布时间】:2021-02-10 08:24:49
【问题描述】:

我喜欢这个在普通 sql 中工作的查询:

SELECT users.id, users.name, roles.name
FROM users
LEFT JOIN model_has_roles ON model_has_roles.model_id = users.id
LEFT JOIN roles ON roles.id = model_has_roles.role_id
ORDER BY roles.name ASC

使用 laravel 我试过这样但它不起作用:

$user = $request->user();

$role = (array) $request->get('role', []);
$order = (array) $request->get('order');

$perPage = $request->get('perPage') ?? 10;

$users = User::where('id', '!=', $user->id);

if(count($role)) {
    if (($key = array_search('admin', $role)) !== false) {
        unset($role[$key]);
    }
    $users = $users->whereHas('roles', function ($query) use($role) {
        return $query->whereIn('name', $role);
    });
} else {
    $users = $users->whereHas('roles', function ($query) {
        return $query->whereIn('name', ['farmer', 'specialist', 'company']);
    });
}

if(count($order) && isset($order['field'])) {
    $orderType = $order['type'] ?? 'ASC';
    if($order['field'] == 'role') {
        $users = $users->leftJoin('model_has_roles', 'model_has_roles.model_id', '=', 'users.id')
        ->leftJoin('roles', 'roles.id', '=', 'model_has_roles.role_id')
        ->orderBy('roles.name', $orderType);
    } else {
        $users = $users->orderBy($order['field'], $orderType);
    }
}

$users = $users->paginate($perPage);

错误信息:

`"message": "SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous (SQL: select count(*) as aggregate from `users` left join `model_has_roles` on` `model_has_roles`.`model_id` = `users`.`id` left join `roles` on `roles`.`id` = `model_has_roles`.`role_id` where `id` != 3 and exists (select * from `roles` inner join `model_has_roles` on `roles`.`id` = `model_has_roles`.`role_id` where `users`.`id` = `model_has_roles`.`model_id` and `model_has_roles`.`model_type` = App\\Models\\User and `name` in (specialist, company)))",

【问题讨论】:

  • $users->leftJoin - $users 的第一个定义在哪里?
  • 错误显示了id != 3 的位置,但您没有向我们展示整个查询。
  • 您的查询中的and name`在哪里?
  • 问题已更新@HoneyBadger
  • $users = User::where('id', '!=', $user->id);更改为 $users = User::where('users.id', '!=', $user->id);

标签: mysql sql laravel eloquent


【解决方案1】:

因为您的两个模型都有 id 并且在 sql 执行后查询 id 列将是不明确的,所以这将对您有所帮助:

$users = User::where('id', '!=', $user->id);

改为

$users = User::where('users.id', '!=', $user->id);

那就试试吧:

$users = $users->select(['users.id', 'users.name', 'roles.name'])
                ->leftJoin('model_has_roles', 'model_has_roles.model_id', '=', 'users.id')
                ->leftJoin('roles', 'roles.id', '=', 'model_has_roles.role_id')
                ->orderBy('roles.name', 'ASC');

【讨论】: