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

Laravel查询生成器的SQL子查询联接问题,sql,laravel,join,Sql,Laravel,Join,我一直在理解Laravel查询生成器和纯SQL之间的融合 我有两张桌子: User:包含具有主键的用户User\u id User\u Action:这是一个包含记录的表,记录的主键为User\u id和操作的datetime 例: 用户 user_id 1 id name 1 john 2 jack 用户操作 user_id datetime action_type 1 2017-12-01 12:10:00 y 1

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

我有两张桌子:

  • User:包含具有主键的用户
    User\u id
  • User\u Action:这是一个包含记录的表,记录的主键为
    User\u id
    和操作的
    datetime
例:

用户

user_id
1
id   name
1    john
2    jack
用户操作

user_id    datetime              action_type
1          2017-12-01 12:10:00   y
1          2017-12-01 12:00:00   x
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
我的需要

现在我想检索一个用户列表,其中包含每个用户的最新操作。因此,我只需要在从
user
user\u action
的连接中获取一行,并且这一行必须是具有最新日期时间的一行。 我的前任也是如此;我只想获取datetime
2017-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\u action
表中得到任何东西,但是如果给定用户的操作是表中最新的操作,它就会工作! 我以为
$join->on
会过滤用户id,但是join子查询没有这个过滤器,我只能在子查询中输入WHERE,因为我没有用户id!这是一个获取用户列表的查询

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`
我错过了一些成功的机会,谢谢你的帮助

试试这个:

$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:

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

用户

user_id
1
id   name
1    john
2    jack
用户操作

user_id    datetime              action_type
1          2017-12-01 12:10:00   y
1          2017-12-01 12:00:00   x
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
                )

        )

)

谢谢,这里缺少的关键是我要完全理解我在做什么,就是在子查询中使用聚合函数。我不知道当时我为什么这么迷路!我做了一些与您类似的事情,但我使用了select链接语法和最大聚合函数:
$query->select('user\u id')->selectRaw('MAX(datetime)as maxDatetime')->groupBy('user\u id')