【问题标题】:Laravel Eloquent union models from relationsships来自关系的 Laravel Eloquent 联合模型
【发布时间】:2020-12-11 00:07:39
【问题描述】:

我有一个用户可以召开来自不同关系的会议。他可以被直接分配到一个有太多关系的会议,他可以有一个有太多关系的用户组,可以有太多太多关系的会议,以及他可以负责一对多关系的会议。
我想为一位用户安排所有会议。我不想合并集合,因为我希望能够直接在数据库中使用像where 这样的功能。我的尝试是合并所有会议 ID,然后通过“whereIn”获取会议。

$ids = $this->meetings()->select('meetings.id')
    ->union($this->meetingsFromGroups()->select('meetings.id'))
    ->union($this->responsibleMeetings()->select('meetings.id'));

return Meeting::whereIn('id', $ids)->get();

当我执行这个时,我得到这个错误:

"SQLSTATE[42000]: 语法错误或访问冲突:1064 您的 SQL 语法有错误;请查看与您的 MySQL 服务器版本相对应的手册,以了解在 'union 附近使用的正确语法(选择 `meetings`。来自 `meetings` 内部的 `id` 在第 1 行加入 `meeting_user_group` on' (SQL:...)" 执行的 SQL:

select *
from `meetings`
where `id` in (
        (
            select `meetings`.`id`
            from `meetings`
                inner join `meeting_user` on `meetings`.`id` = `meeting_user`.`meeting_id`
            where `meeting_user`.`user_id` = 1
        )
        union
        (
            select `meetings`.`id`
            from `meetings`
                inner join `meeting_user_group` on `meeting_user_group`.`meeting_id` = `meetings`.`id`
                inner join `user_groups` on `user_groups`.`id` = `meeting_user_group`.`user_group_id`
                inner join `user_user_group` on `user_user_group`.`user_group_id` = `user_groups`.`id`
            where `user_user_group`.`user_id` = 1
        )
        union
        (
            select `meetings`.`id`
            from `meetings`
            where `meetings`.`responsible_id` = 1
                and `meetings`.`responsible_id` is not null
        )
    )

关系:

    public function responsibleMeetings(): HasMany {
        return $this->hasMany(Meeting::class, 'responsible_id');
    }

    public function meetings(): BelongsToMany {
        return $this->belongsToMany(Meeting::class)->withTimestamps();
    }

    public function meetingsFromGroups(): HasManyDeep {
        return $this->hasManyDeepFromRelations($this->userGroups(), (new UserGroup())->meetings());
    }

我正在为meetingsFromGroups 使用包Staudenmeir\EloquentHasManyDeep

我不能在整个会议上使用union,因为那样我会得到

SQLSTATE[21000]:基数违规:1222 使用的 SELECT 语句有不同的列数

因为数据透视字段。

必须如何更改 SQL 才能使其工作,我如何使用 Eloquent 做到这一点?

【问题讨论】:

    标签: sql laravel eloquent laravel-7.x


    【解决方案1】:

    默认情况下,whereIn 期望数组对数组项执行 IN() 子句,但在您的情况下,您正在发送联合查询,这就是它抛出错误的原因。

    $ids = $this->meetings()->select('meetings.id')
        ->union($this->meetingsFromGroups()->select('meetings.id'))
        ->union($this->responsibleMeetings()->select('meetings.id'))
        ->pluck('id')->all();
    
    return Meeting::whereIn('id', $ids)->get();
    

    另外whereIn 也接受闭包方法,但不确定如何在闭包内调用这些相关的$this->meetings()$this->meetingsFromGroups()$this->responsibleMeetings()

    return Meeting::whereIn('id', function($query){
        $query->select('...')
        ...;
    })->get();
    

    【讨论】:

    • 我用 pluck 替换了不推荐使用的列表方法,现在它可以工作了。谢谢!
    猜你喜欢
    • 2016-02-26
    • 2021-10-01
    • 2018-10-20
    • 2021-07-04
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 2017-01-12
    • 1970-01-01
    相关资源
    最近更新 更多