当前位置: 首页 > 知识库问答 >
问题:

Laravel查询生成器的SQL子查询联接问题

朱阳曜
2023-03-14

我一直在理解Laravel查询生成器和纯SQL之间的融合。

我有2张桌子:

  • user:包含具有主键user_id
  • 的用户
  • User_Action:这是一个表,其中包含由user_id和动作的datetime组成的PRIMARYs记录。

ex:

使用者

user_id
1

用户操作

user_id    datetime              action_type
1          2017-12-01 12:10:00   y
1          2017-12-01 12:00:00   x

我的需要:

现在我想检索一个用户列表,其中包含每个用户的最新操作。因此,我只需要在从useruser\u action的连接中获取一行,并且这一行必须是具有最新日期时间的一行。我的前任也是如此;我只想获取datetime2017-12-01 12:10:00带有左连接的记录(即使没有操作也检索用户)。

我尝试了以下方法:

$userActionSubquery = DB::table('user_action')
        ->select()
        ->orderBy('datetime', 'DESC')
        ->limit(1);
$query->leftJoinSub($userActionSubquery, 'user_action', function ($join) {
         $join->on('user_action.user_id', '=', 'user.user_id');
})->groupBy('user_id');

通过这样做,我不会从user_action表中得到任何东西,但是如果给定用户的操作是表中最新的,它就可以工作!我以为$join-

PS:生成的查询是

SELECT user.user_id FROM user left join (SELECT * FROM user_action ORDER BY datetime DESC LIMIT 1) as user_action on user_action.user_id = user.user_id WHERE user.tenant_id in ('7') GROUP BY `user_id`

我错过了成功的东西,谢谢你的帮助!


共有1个答案

郑浩博
2023-03-14

试试这个:

$sub = \DB::table('user_action')
    ->select([
        'user_id',
        \DB::raw('SUBSTRING_INDEX( GROUP_CONCAT( action_type ORDER BY datetime DESC ), ",", 1 ) AS last_action_type')
    ])
    ->groupBy('user_id');

$data = \DB::table('user')
    ->leftJoinSub($sub, 'tmp', function ($join) {
        $join->on('tmp.user_id', '=', 'user.id');
    })->get();

sql:

SELECT * FROM user LEFT JOIN ( SELECT user_id, SUBSTRING_INDEX( GROUP_CONCAT( action_type ORDER BY datetime DESC ), ',', 1 ) AS last_action_type FROM user_action GROUP BY user_id ) AS tmp ON tmp.user_id = user.id

它在我的测试环境中工作:

使用者

id   name
1    john
2    jack

用户操作

id   user_id   datetime              action_type
1    1         2020-09-24 23:51:00   login
2    1         2020-09-24 23:51:20   search
3    2         2020-09-24 23:30:00   login
4    2         2020-09-25 00:00:00   coding

后果

Illuminate\Support\Collection Object
(
    [items:protected] => Array
        (
            [0] => stdClass Object
                (
                    [id] => 1
                    [name] => john
                    [user_id] => 1
                    [last_action_type] => search
                )

            [1] => stdClass Object
                (
                    [id] => 2
                    [name] => jack
                    [user_id] => 2
                    [last_action_type] => coding
                )

        )

)
 类似资料:
  • 问题内容: 对于开发人员何时使用联接而不是子查询是否有经验法则还是相同的? 问题答案: 取决于RDBMS。您应该比较两个查询的执行计划。 根据我对Oracle 10和11的经验,执行计划始终是相同的。

  • 问题内容: 遇到了一些严重的问题,无法解决如何针对我的情况建立适当的查询。.可以肯定的是,这取决于正确地连接表,但是经过大量的谷歌搜索之后,我似乎无法弄清楚… 我有下表。 和… 和… 希望我能够正确解释这一点。.我在Main中有一堆记录,我需要从中获取信息。.我需要能够对WhenDate和TypeID进行过滤。我还需要从链接到StatusID的状态表中获取StatusText。 问题: 次要表链接

  • 我有下面的查询,我正试图将其转换为Laravel的查询生成器,以便利用自动转义等功能。 实际上,查询所说的是“获取所有主题的名称,如果它们有匹配的report_comment(通过中间的表),将其与主题一起返回”(对于给定的条件,主题有一个或零report_comments)...如果我直接在MySQL中运行查询并返回我期望的结果,查询就可以工作。目前是硬编码的,但最终将成为占位符,以便可以传入任

  • 问题内容: 我正在尝试将SQL转换为SQLAlchemy。我要查询的SQL版本如下: 我的SQLAlchemy查询如下: 我收到一个错误 如果我将SQLAlchemy查询调整为以下内容: 结果= query.all() 我得到一个错误 任何帮助,将不胜感激,谢谢! 问题答案: 一旦调用,就无法访​​问 对象 ,而只能通过访问器访问列。 而是执行以下操作:仅加载所需的列,以避免任何名称冲突: 然后在

  • 我试图从一个表中选择所有结果,并在用户ID匹配时与另一个表合并。 我有三个表:runs、users和一个run\u用户透视表。我想从数据透视表中的“运行”和其他列(即“已完成”、“粘性”、“上次测试”和“难度”)中选择所有结果,但只从当前用户的“运行用户”中提取数据。 在原始SQL中,我通过一个带有AND语句的左连接成功地做到了这一点: 如何通过查询生成器执行此操作,有何建议?我可以在Larave

  • 我有一个问题,使laravel查询: 我想举个例子: 我有这个但不起作用: