У нас есть таблица сообщений, а user_id — это внешний ключ. Например, я хочу выбрать посты для этих пользователей
$users=[1,2,13,16,17,19];
$posts = Post::whereIn('user_id', $users)->paginate(10);
Но я хочу, чтобы у пользователя 1 и 2 было только два сообщения в выводе, для остальных пользователей количество сообщений не ограничено.
Note: User 1 and 2 are not always within the
$usersarray, and due to the condition, one or both of them may not be in the array.
У вас есть решение для меня?
Всегда ли 1 и 2 должны быть ограничены двумя постами? а какие два поста первые два поста или последние два поста?
@Mozammil Пользователь 1 Два сообщения и пользователь 2 Всего два сообщения 4 сообщения
@Rehan Да, это всегда 1 и 2, и нужно выбрать два последних сообщения этих пользователей.
Что вы пробовали? Покажи нам свой код. SO не является службой написания кода.
@Don'tPanic Я хотел использовать союз, но поскольку он использовался для другого результата, я пытаюсь найти лучшее решение.
Покажи нам свой код. Посетите справочный центр и прочтите как спросить и как создать минимальный, полный и проверяемый пример.
@Don'tPanic Спасибо, я проверю еще раз






Вы можете сделать это с помощью ->take()
$posts = [];
$users=[1,2,13,16,17,19];
foreach($users as $user)
{
if ($user == 1 || $user == 2)
{
$posts[] = Post::where('user_id', $user)->take(2)->get();
}
else
{
$posts[] = Post::where('user_id', $user)->get();
}
}
Подробнее читайте на https://laravel.com/docs/5.7/queries
Не рекомендуется ли запускать запросы внутри цикла. Этого следует избегать любой ценой.
В этом ответе вы можете отфильтровать, сколько постов вы хотите получить для user 1 и user 2, используя ->take(), а остальные займут все посты.
@ Рехан, о, я вижу? но могу я спросить, почему?
Даже если это потребуется, запросы выполняются в цикле, которого следует избегать.
Предположим, у вас есть 100 тыс. строк, запросы должны выполняться 100 тыс. раз и влиять на производительность приложения.
Рекомендуется извлекать данные в одном запросе, а затем изменять их с помощью цикла.
Проверьте мой ответ для решения.
Вы можете попробовать эту альтернативу:
$posts = [];
$users=[1,2,13,16,17,19];
$userWithJustTwo = [1,2];
$result = array_intersect($users, $userWithJustTwo);
$posts[] = Post::whereIn('user_id', $result)->orderBy('created_at', 'desc')->take(2)->get();
$array = array_diff($users, userWithJustTwo);
$posts[] = Post::whereIn('user_id', $array)->get();
Это мы не получаем последние два сообщения, так как OP запросил пользователя [1,2]
@Maraboc Спасибо, позвольте мне проверить это
Вы не можете добиться этого в одном запросе, нам нужно взять его отдельно, как это
$users=[1,2,13,16,17,19];
// first take all the post except the two
$posts = Post::whereIn('user_id', $users)->whereNotIn('user_id', [1,2])->get()->toArray();
// then take one user 1 post in desc and limit it by 2
$userOnePost = Post::whereIn('user_id', $users)->where('user_id', 1)->limit(2)->orderBy('post.id', 'desc')->get()->toArray();
// then take one user 2 post in desc and limit it by 2
$userTwoPost = Post::whereIn('user_id', $users)->where('user_id', 2)->limit(2)->orderBy('post.id', 'desc')->get()->toArray();
// merge all the array
$allPost = array_merge(posts,$userOnePost,userTwoPost);
Проверьте это и дайте мне знать, было ли это полезно @Vajiheh habibi
Спасибо, позвольте мне проверить это
попробуйте этот метод:
$users = User::whereNotIn('id', [1,2])->pluck('id');
$posts = [];
$posts[] = Post::whereIn('user_id', [1,2])->take(2)->get();
$posts[] = Post::whereIn('user_id', $users)->get();
если вы хотите получить последнюю версию post, используйте это:
$posts[] = Post::whereIn('user_id', [1,2])->latest('created_at')->take(2)->get();
вы также можете использовать группировку параметров, как это
DB::table('post')
->whereIn('user_id', $users)
->where(function ($query) {
$query->whereIn('user_id', [1,2])->limit(2)
->orWhereNotIn('user_id', [1,2]);
})
->get();
Пользователь 1 и пользователь 2 будут иметь по 2 сообщения каждый или они будут иметь два сообщения вместе?