Laravel查询生成器的SQL子查询联接问题
我一直在理解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
- 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
的连接中获取一行,并且这一行必须是具有最新日期时间的一行。
我的前任也是如此;我只想获取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\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')