Как найти только последнюю строку из второй таблицы вместе с первой строкой таблицы - PullRequest
0 голосов
/ 13 марта 2019

У меня есть две таблицы. журналы и тома . Таблица журнала имеет уникальные строки, а таблица томов имеет строки на основе идентификатора таблицы журнала, имя - journal_id (может быть несколько).

таблица журналов:

id | journal_name

1  | journal1
2  | journal2

Таблица томов:

id | journal_id | volume_name

1  |    1       |  volume1
2  |    1       |  volume2
3  |    1       |  volume3
4  |    2       |  volume4
5  |    2       |  volume5

Теперь мне нужно соединиться со строкой из таблицы журнала и только последними строками томов на основе journal_id .

Результат должен быть:

id | journal_name | journal_id | volume_name

1  | journal1     |   1        |   volume3
2  | journal2     |   2        |   volume5

Не все строки таблицы томов. (Нужны только последние строки из каждой группы journal_id).

требуемый результат запроса MySQL:

SELECT J.journal_name,V.id,V.journal_id FROM journals AS J 
INNER JOIN (SELECT *
FROM volumes
WHERE id IN (
SELECT MAX(id)
FROM volumes
GROUP BY journal_id
)) AS V ON J.id = V.journal_id

Теперь моя попытка в laravel:

контроллер:

public function index()
{
$volumes = volume::with('volumes')->orderBy('id','desc')->limit(1)->get();
    return view('welcome',compact('volumes'));
}

Объемная модель:

function volumes()
 {
      return $this->belongsTo(journal::class, 'journal_id');
 }

Но он дает только одну строку из всей таблицы томов. Мне нужна последняя строка из каждой группы journal_id в таблице томов.

Ответы [ 2 ]

1 голос
/ 13 марта 2019

Вы можете использовать HasOne отношение:

class Journal extends Model
{
    public function latestVolume()
    {
        return $this->hasOne(Volume::class)->orderByDesc('id');
    }
}

$journals = Journal::with('latestVolume')->get();

Имейте в виду, что при этом все тома будут извлечены из базы данных. Затем он отбрасывает «старые».

Если вы хотите улучшить производительность путем действительно извлечения только последнего тома, вы можете использовать этот пакет, который я создал: https://github.com/staudenmeir/eloquent-eager-limit

Пакет позволяет применять limit() к отношениям:

class Journal extends Model
{
    use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;

    public function latestVolume()
    {
        return $this->hasOne(Volume::class)->orderByDesc('id')->limit(1);
    }
}
0 голосов
/ 13 марта 2019

Правильный способ определения моделей:

Журнал модель

function volumes()
{
    return $this->belongsTo(Volume::class);
}

Объемная модель

function journals()
{
    return $this->hasMany(Journal::class);
}

Теперь $journal->volumes должен вернуть все тома, принадлежащие этому журналу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...