#laravel #eloquent #greatest-n-per-group #one-to-many #eloquent-relationship
#laravel #красноречивый #наибольшее число на группу #один ко многим #красноречивый-отношение
Вопрос:
Необходимо получить отдельную строку.
Есть ли какой-либо способ в laravel eloquent избежать дублирования данных. Необходимо получить уникальных пользователей после объединения с таблицей изображений.
Теперь я получаю одних и тех же пользователей, нужно избегать повторения одного и того же пользователя.
Образ модели
public function user()
{
return $this->belongsTo('AppUser');
}
Таблица пользователя
id | name
---------
| 1| Joe
| 2| Ben
| 3| Don
Таблица изображений
id | name | user_id
---------------------
| 1 | 1.png | 3
| 2 | 2.png | 1
| 3 | 3.png | 1
| 4 | 4.png | 2
присоединяйтесь с помощью eloquent :
Image::with('user')->orderBy('id', 'desc')->paginate(10);
Требуемый вывод
"data": [
{
"id": 4,
"name": "4.png",
"user_id": 2,
"user": {
"id": 2,
"name": "Ben",
}
},
{
"id": 3,
"name": "3.png",
"user_id": 1,
"user": {
"id": 1,
"name": "Joe",
}
},
{
"id": 1,
"name": "1.png",
"user_id": 3,
"user": {
"id": 3,
"name": "Don",
}
},
],
Комментарии:
1. на самом деле есть
distinct()
функция, которую вы можете использовать.2. @Aless55 Я пробовал разные методы, используя distinct, не работает.
3. Пожалуйста, подумайте, ответьте как принятый или проголосуйте «за» или «против»
Ответ №1:
Похоже, вам нужны все пользователи и только одно из изображений для каждого пользователя. Вы могли бы сделать что-то вроде следующего, чтобы добавить связь изображения с моделью пользователя:
public function image()
{
return $this->hasOne('AppImage')->orderBy('id', 'desc');
}
Затем вы получите доступ к этим данным следующим образом User::has('image')->with('image')
;
Комментарии:
1. Мне нужно сделать distinct для «user_id», есть ли какой-либо способ в laravel eloquent достичь этого?
2. Это почти работает, но я должен получить результат на основе последнего изображения. Делая это по-своему, результат будет зависеть от пользователей. На самом деле в желаемом выводе оно должно быть по убыванию, я это исправил
3. Это должно дать вам последнее изображение для каждого пользователя, я предположил, что вам нужно только одно изображение для каждого пользователя. Это работает у вас сейчас или вам все еще нужна помощь? Не стесняйтесь добавлять свой текущий код, если вам все еще нужна помощь.
Ответ №2:
Чтобы получить уникальные результаты от Eloquent, вызовите метод unique() в конце цепочки методов.
Image::with('user')
->orderBy('id', 'desc')
->paginate(10)
->unique() // Like this
Если вышеуказанный метод не работает, попробуйте приведенный ниже.
Image::with('user')
->orderBy('id', 'desc')
->paginate(10)
->unique()
->values()
Комментарии:
1. Я добавил еще одну вещь в ответ, теперь попробуйте еще раз.
Ответ №3:
Чтобы получить последнее изображение для каждого пользователя, вы можете использовать самосоединение, например
Схема
CREATE TABLE users
(`id` int, `name` varchar(3))
;
INSERT INTO users
(`id`, `name`)
VALUES
(1, 'Joe'),
(2, 'Ben'),
(3, 'Don')
;
CREATE TABLE images
(`id` int, `name` varchar(5), `user_id` int)
;
INSERT INTO images
(`id`, `name`, `user_id`)
VALUES
(1, '1.png', 3),
(2, '2.png', 1),
(3, '3.png', 1),
(4, '4.png', 2)
;
Запрос
select a.*, u.*
from images a
left join images b on a.user_id = b.user_id
and a.id < b.id
join users u on u.id = a.user_id
where b.user_id is null
order by a.id desc
Конструктор запросов
DB::table('images as a')
->select('a.*, u.*')
->leftJoin('images as b', function ($join) {
$join->on('a.user_id', '=', 'b.user_id')
->whereRaw(DB::raw('a.id < b.id'));
})
->join('users as u', 'u.id', '=', 'a.user_id' )
->whereNull('b.user_id')
->orderBy('a.id', 'desc')
->get();