Laravel 为 2 列加入同一张表

Posted

技术标签:

【中文标题】Laravel 为 2 列加入同一张表【英文标题】:Laravel join same table for 2 columns 【发布时间】:2016-06-26 23:43:52 【问题描述】:

我目前有这个代码:

        return Datatable::query($query = DB::table('acquisitions')
            ->where('acquisitions.deleted_at', '=', null)
            ->where('acquisitions.status', '!=', 2)
            ->join('contacts', 'acquisitions.contact_id', '=', 'contacts.id')
            ->join('user', 'acquisitions.user_id', '=', 'user.id')
            ->select('contacts.*', 'acquisitions.*', 'acquisitions.id as acquisitions_id', 'user.first_name as supervisor_first_name', 'user.last_name as supervisor_last_name', 'user.id as user_id'))

用户表中的数据用于 2 列:acquisitions.supervisor_idacquisitions.user_id。我需要这两个表的first_namelast_name,但是上面的查询目前只使用acquisitions.user_id 字段中的id。我也尝试使用表别名,这也不起作用,我认为我在这里做错了。

简而言之:我还需要查询根据来自acquisitions.supervisor_id 的ID 为用户选择数据,并将其作为supervisor_first_namesupervisor_last_name 提供。

【问题讨论】:

您是否尝试过在 select 语句中使用 DB::raw()。 不,我有点不知道如何将它实现到查询中,如果你能帮助我解决这个问题,我将不胜感激。通常情况下,我只会用 eloquent 来做,不幸的是,由于插件,这在此处是不可能的。谢谢! 【参考方案1】:

根据您对另一个答案的倒数第二条评论,您需要每个参考表的自联接。试试这个:

$result = DB::select('SELECT
u.name user_first_name,
u.last_name user_last_name,
u.email user_email,
s.name supervisor_name,
s.last_name supervisor_last_name,
s.email supervisor_email
FROM acquisitions a
JOIN users u ON a.user_id = u.id
JOIN users s ON a.supervisor_id = s.id');

return $result;

注意$resultStdClass 对象的数组,而不是集合,但您仍然可以对其进行迭代并调用当前项的值:

foreach ($result as $item) 
    print($item->supervisor_first_name);

如果您需要 WHERE 子句,例如要从 acquisitions 获取特定用户的行,您可以通过向查询中添加参数来实现,如下所示:

$result = DB::select('SELECT
u.name user_first_name,
u.last_name user_last_name,
u.email user_email,
s.name supervisor_name,
s.last_name supervisor_last_name,
s.email supervisor_email
FROM acquisitions a
JOIN users u ON a.user_id = u.id
JOIN users s ON a.supervisor_id = s.id
WHERE a.user_id = ?
', [3]);

编辑

如果您需要结果集为Collection,您可以使用hydrate 方法轻松地将数组转换为1:

$userdata = \App\User::hydrate($result); // $userdata is now a collection of models

【讨论】:

非常感谢,遗憾的是我现在确实遇到了这个包无法使用它的问题,因为它似乎需要收集__clone method called on non-object 确保您确实得到了有效的结果,请查看我的编辑 查询确实有效,但没有返回我所需要的。现在我只得到我在下面(在评论中)指定的数据,但缺少采集表中的所有其他值。关于转换为集合,如果数据不是来自特定表,那是否仍然有效?我从未使用过该功能,我的意思是在这种情况下,数据集实际上应该来自采集表,并且只包含当前查询(您在上面创建的)正在输出的数据,我希望您知道我的意思,我很已经累了。非常感谢您的宝贵时间! TBH 我没有使用太多hydrate,但由于它是 Eloquent 模型的一种方法,我想它“更喜欢”从单个表中获取数据,也可能从它的关系中获取数据。无论如何,您必须测试哪个更适合您。至于你需要从采集中获得的“其他”数据,只需将其附加在SELECT 语句中即可。 Eloquent 怎么做到这一点?【参考方案2】:

应该是这样的;

return Datatable::query($query = DB::table('acquisitions')
    ->where('acquisitions.deleted_at', '=', null)
    ->where('acquisitions.status', '!=', 2)
    ->join('contacts', 'acquisitions.contact_id', '=', 'contacts.id')
    ->join('user', 'acquisitions.user_id', '=', 'user.id')
            ->select( \DB::raw("  contacts.*, acquisitions.*, acquisitions.id as acquisitions_id, user.first_name as supervisor_first_name, user.last_name as supervisor_last_name, user.id as user_id   ") )
);

【讨论】:

谢谢,但这对我没有帮助。我知道如何在选择中使用原始查询,但是我仍然不知道正确的查询必须如何正确分配值:/ 除了我很确定我需要先调整连接。 您不能在查询中使用别名,如果这是您想要实现的。您可以做的是做一个子查询,并在 where 语句中使用输出。您能否提供有关该问题的更多详细信息,因为我不太了解确切的问题。 我有 2 张桌子。 useracquisitions。表 acquisitions 包含 2 列:user_idsupervisor_iduser 包含 first_namelast_name。现在我想为 supervisor_id 和 user_id 选择名字和姓氏作为 supervisor_first_name, supervisor_last_name, user_first_name, user_first_name【参考方案3】:
$devices = DB::table('devices as d')
->leftJoin('users as au', 'd.assigned_user_id', '=', 'au.id')
->leftJoin('users as cu', 'd.completed_by_user_id', '=', 'cu.id')
->select('d.id','au.name as assigned_user_name','cu.name as completed_by_user_name');

也可以点击这个链接

https://github.com/yajra/laravel-datatables/issues/161

【讨论】:

以上是关于Laravel 为 2 列加入同一张表的主要内容,如果未能解决你的问题,请参考以下文章

避免多次加入同一张表

Laravel Eloquent Eager Loading:加入同一张表两次

加入同一张表

Django ORM查询,不同的值并加入同一张表

两个excel表,有一列内容相同,怎么把这两张表合并?

LINQ 按同一列连接多个表