【问题标题】:How can I use JOIN in order to retrieve rows according to WHERE statements in distinct tables?如何使用 JOIN 根据不同表中的 WHERE 语句检索行?
【发布时间】:2015-05-26 02:43:45
【问题描述】:

我有一个数据库,里面控制着一些orders,每个订单有很多items,自然是一个属于某个部门的用户提交的订单。

每个用户都属于某个角色,因此订单由具有不同更高角色的不同users 连续审核。我使用delegate 字段控制下一个应该对订单执行操作的用户。

我将描述我的一些表格及其相关字段:

Department:
- id
- name

User:
- id
- name
- department_id
- role

Order:
- id
- user_id
- delegate // Here I got an enum for the multiple roles a user can get

Revision:
- id
- order_id
- user_id
- operation

查询

所以我需要的是一个查询来检索其用户属于给定department_id 的所有订单,并且delegate 字段等于一个提供的参数或revisions 表中有记录user_id等于另一个提供的参数

我得到了什么......

在 Eloquent ORM 的帮助下,我得到了我所需结果的第一部分的这种查询方式:

select `orders`.*, `users`.`department_id` from `orders` inner join `users` on `users`.`id` = `orders`.`user_id` where `users`.`department_id` = '1' and `delegate` = 'GERENTE DE DEPARTAMENTO' limit 2 offset 0

为了包含 OR,其中revisions 表中有记录,user_id 等于另一个提供的参数我尝试将查询的一部分附加到查询:

JOIN orders on revisions WHERE user_id = 5 

但是没用……

我尝试的整个查询是:

select `orders`.*, `users`.`department_id` from `orders` inner join `users` on `users`.`id` = `orders`.`user_id` where `users`.`department_id` = '1' and `delegate` = 'GERENTE DE DEPARTAMENTO' JOIN orders on revisions WHERE user_id = 5 

示例

我在查询示例中使用硬编码参数,因为它们来自真实示例……在这种情况下,我只需要获取用户属于 deparment_id 1、delegate 的整个订单是 'GERENTE DE DEPARTAMENTO'或者如果revisions 表中有行将user_id 设置为5

Orders:

+----+---------+-------------------------+
| id | user_id | delegate                |
+----+---------+-------------------------+
|  1 |       4 | GERENTE DE DEPARTAMENTO |
|  2 |       2 | SUPERVISOR DE COMPRAS   |
+----+---------+-------------------------+


Revisions:
+----+---------+----------+
| id | user_id | order_id |
+----+---------+----------+
|  1 |       5 |        2 |
|  2 |       5 |        2 |
+----+---------+----------+

一个有效的查询应该只接受订单 1 和 2。 我怎样才能完成它?我对所需的 MySQL 很感兴趣,如果它是基于 Eloquent 的查询,我是一个 PLUS。

【问题讨论】:

    标签: mysql laravel join eloquent


    【解决方案1】:

    如果我说得对,即。你需要:

    orders that delegate= $delegate AND have user_id= x if that user got as department_id= $department_id at users, OR revisions by user with id = $userId

    那么这就是Eloquent方式:

    Order::where('delegate', $delegate)
      ->whereHas('user', function ($q) use ($depId) {
        $q->where('department_id', $depId);
      })->orWhereHas('revisions', function ($q) use ($userId) {
        $q->where('user_id', $userId);
      })
    ->get();
    

    【讨论】:

    • 我需要的是any orders that delegate= $delagete AND have user_id= x if that user got as department_id= $department_id at users, OR revisions by user with id = $userId
    • 在这种情况下,这样的查询是否假定我在模型中建立了关系?在我想知道->whereHas('user'... 中的用户到底应该是什么之前,我问... 一个关系函数,一个表?
    • 是的,userOrder belongsTo User 关系,revisionsOrder hasMany Revision 关系。您要求 Eloquent 解决方案,所以我假设您已经定义了它们。
    • 太好了,谢谢...生成的查询与另一个响应中的查询有多相似?
    • 它与left join distinct 之类的东西相去甚远。只需构建它并使用toSql 而不是get,您就会看到。它基本上调用 2 个子查询(每个 whereHas 1 个)。
    【解决方案2】:

    你可以使用左连接。

    您的查询可能如下所示:

    select distinct `orders`.*, `users`.`department_id` from `orders`
           left join `users` on `order`.`user_id`=`users`.`id`
           left join `revisions` on `order`.`id`=`revisions`.`order_id`
                                and `revisions`.`user_id`=?
        where `users`.`department_id`=?
        and (`order`.`delegate`=? or `revisions`.`id` is not null)
    

    【讨论】:

    • 这不包括委托参数并且可能重复订单..:/
    • 左连接确保左表(例如订单)按原样显示——即没有重复的行,没有丢失的行。
    • 我刚刚检查过,它正在重复行
    • 在 SOP 中您有 x and y OR z。我不确定是否将其解释为(x and y) OR zx and (y OR z),但我认为如何更改查询以匹配很清楚:)
    • 抱歉,我得回去工作了。我想你会明白的~
    猜你喜欢
    • 1970-01-01
    • 2021-02-17
    • 2012-12-08
    • 1970-01-01
    • 2017-07-27
    • 2020-01-08
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多