如何使用 Laravel eloquent 获取 table 中每个用户的最新记录
How to fetch latest record of each user in a table using Laravel eloquent
我在 table 中有 n 个用户,对于每个用户,我将他们的登录和注销时间保存在单独的 table 中。我想使用 Laravel eloquent.
获取 2 天未登录用户的详细信息
用户table结构
id | name | email
日志table结构
id |action | user_id | created_at | updated_at
到目前为止我已经做了这么多:
$users = LogsData::where('action','Login')->where('created_at','<',Carbon::now()->subDays(1))->get();
但是输出中也有在 2 天内登录的用户。
编辑:
我收到了查询,我需要将其转换为 eloquent.
我自己解决了。这是解决方案:
SELECT t1.* FROM actions t1
JOIN (SELECT user_id, MAX(id) as maxid FROM actions where action = "LOGIN" GROUP BY user_id) t2
ON t1.user_id = t2.user_id and t1.id = t2.maxid
where created_at < NOW() - INTERVAL 2 DAY
如果只需要获取每个用户的最后一条数据,可以对id
desc进行排序,然后根据user_id
进行分组,得到最新的数据
$users = LogsData::where('action','Login')
->whereDate('created_at','<',Carbon::today()->subDays(1))
->orderBy('id', 'DESC')
->groupBy('user_id')
->get();
要使用 groupBy
,您必须将配置值中的 strict
更改为 false
。但是如果你不想改变你的配置文件,这个查询可以帮助你。你只需要将它翻译成laravel查询版本
SELECT * FROM log_datas AS ld WHERE ld.action = 'Login' AND ld.id IN (SELECT MAX(id) FROM log_datas WHERE created_at < DATE_SUB(NOW(), INTERVAL 1 DAY) GROUP_BY user_id)
你需要先加入日志table,因为MySQL总是寻找阻力最小的路径,你需要反过来加入:可能不存在日志条目小于 1 天。
$users = DB::from('users')
->leftJoin('logs', function ($join) {
$join->on('users.id', '=', 'logs.user_id')
->where('logs.action', '=', 'Login')
->where('logs.created_at', '>=', Carbon::now()->subDays(2));
})
->whereNull('logs.id')
->get();
也许尝试使用 eloquent 关系
记下您的命名空间,确保 App\LogsData 在这里是正确的
// in your User Model
public function logsData()
{
return $this->hasMany('App\LogsData');
}
// in your LogsData Model
public function user()
{
return $this->belongsTo('App\User');
}
public function scopeLoginActions($query)
{
return $query->where('action', 'Login');
}
然后您可以使用
访问数据
User::whereHas('logsData', function ($query) {
$query->loginActions()->where('created_at', '<', now()->subDays(2));
})->get();
// and if you require the login records
User::with('logsData')->whereHas('logsData', function ($query) {
$query->loginActions()->where('created_at', '<', now()->subDays(2));
})->get();
// and if you require an individual login record
User::with(['logsData' => function($query) {
$query->loginActions()->where('created_at', '<', now()->subDays(2))->first();
})->whereHas('logsData', function ($query) {
$query->loginActions()->where('created_at', '<', now()->subDays(2));
})->get();
我在 table 中有 n 个用户,对于每个用户,我将他们的登录和注销时间保存在单独的 table 中。我想使用 Laravel eloquent.
获取 2 天未登录用户的详细信息用户table结构
id | name | email
日志table结构
id |action | user_id | created_at | updated_at
到目前为止我已经做了这么多:
$users = LogsData::where('action','Login')->where('created_at','<',Carbon::now()->subDays(1))->get();
但是输出中也有在 2 天内登录的用户。
编辑: 我收到了查询,我需要将其转换为 eloquent.
我自己解决了。这是解决方案:
SELECT t1.* FROM actions t1
JOIN (SELECT user_id, MAX(id) as maxid FROM actions where action = "LOGIN" GROUP BY user_id) t2
ON t1.user_id = t2.user_id and t1.id = t2.maxid
where created_at < NOW() - INTERVAL 2 DAY
如果只需要获取每个用户的最后一条数据,可以对id
desc进行排序,然后根据user_id
进行分组,得到最新的数据
$users = LogsData::where('action','Login')
->whereDate('created_at','<',Carbon::today()->subDays(1))
->orderBy('id', 'DESC')
->groupBy('user_id')
->get();
要使用 groupBy
,您必须将配置值中的 strict
更改为 false
。但是如果你不想改变你的配置文件,这个查询可以帮助你。你只需要将它翻译成laravel查询版本
SELECT * FROM log_datas AS ld WHERE ld.action = 'Login' AND ld.id IN (SELECT MAX(id) FROM log_datas WHERE created_at < DATE_SUB(NOW(), INTERVAL 1 DAY) GROUP_BY user_id)
你需要先加入日志table,因为MySQL总是寻找阻力最小的路径,你需要反过来加入:可能不存在日志条目小于 1 天。
$users = DB::from('users')
->leftJoin('logs', function ($join) {
$join->on('users.id', '=', 'logs.user_id')
->where('logs.action', '=', 'Login')
->where('logs.created_at', '>=', Carbon::now()->subDays(2));
})
->whereNull('logs.id')
->get();
也许尝试使用 eloquent 关系
记下您的命名空间,确保 App\LogsData 在这里是正确的
// in your User Model
public function logsData()
{
return $this->hasMany('App\LogsData');
}
// in your LogsData Model
public function user()
{
return $this->belongsTo('App\User');
}
public function scopeLoginActions($query)
{
return $query->where('action', 'Login');
}
然后您可以使用
访问数据
User::whereHas('logsData', function ($query) {
$query->loginActions()->where('created_at', '<', now()->subDays(2));
})->get();
// and if you require the login records
User::with('logsData')->whereHas('logsData', function ($query) {
$query->loginActions()->where('created_at', '<', now()->subDays(2));
})->get();
// and if you require an individual login record
User::with(['logsData' => function($query) {
$query->loginActions()->where('created_at', '<', now()->subDays(2))->first();
})->whereHas('logsData', function ($query) {
$query->loginActions()->where('created_at', '<', now()->subDays(2));
})->get();