Как получить последнюю запись каждого пользователя в таблице, используя Laravel eloquent - PullRequest
0 голосов
/ 03 апреля 2020

У меня есть n пользователей в таблице, и для каждого пользователя я сохраняю их время входа и выхода в отдельной таблице. Я хочу получить информацию о пользователях, которые не вошли в систему в течение 2 дней, используя Laravel eloquent.

Структура таблицы пользователей

id | name | email

Структура таблицы журнала

id |action | user_id | created_at | updated_at

Пока я сделал так много:

$users = LogsData::where('action','Login')->where('created_at','<',Carbon::now()->subDays(1))->get();

Но на выходе есть пользователи, которые также вошли в систему в течение 2 дней.

РЕДАКТИРОВАТЬ: я получил запрос, Мне нужно преобразовать это в красноречивое.

Я решил это сам. Вот решение:

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

Ответы [ 3 ]

0 голосов
/ 03 апреля 2020

Сначала вам нужно присоединиться к таблице журналов, а поскольку 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();
0 голосов
/ 03 апреля 2020

Возможно, попробуйте использовать красноречивые отношения

Обратите внимание на ваши пространства имен, убедитесь, что, например, 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();
0 голосов
/ 03 апреля 2020

Если вам нужно только получить последние данные каждого пользователя, вы можете отсортировать id des c, а затем сгруппировать по user_id, чтобы получить последние данные

$users = LogsData::where('action','Login')
                 ->whereDate('created_at','<',Carbon::today()->subDays(1))
                 ->orderBy('id', 'DESC')
                 ->groupBy('user_id')
                 ->get();

для использования groupBy, вы должны изменить strict со значения конфигурации на false. Но если вы не хотите использовать groupBy, этот запрос может вам помочь. Вам просто нужно перевести его на 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)
...