dark_firewall
@dark_firewall
Программист C#

Как выбрать все последние запись где recipient = 1?

в место того чтобы выбрать по 1 записи к каждому пользователю он повторяет запись код ниже
echo "<div class=messagess>";
	$msg=$db->query("SELECT * FROM `messages` WHERE `recipient`='{$_SESSION['id']}'");
	while($r=mysqli_fetch_array($msg)){
		$users=$db->query("SELECT * FROM `users` WHERE `id`='{$r['author']}'");
		while($r2=mysqli_fetch_array($users)){
			$avatar=select('background', 'avatar', 'id', $r['author'], true);
			$style = '';
			if($r2['level'] != 'Пользователь'){
				$style='mm';
			}

			echo "<a href=/messages?type=private&id=".$r2['id'].">";
			echo "<div class=user>";
			echo "<img class='ava $style' src=".photo($avatar[0])."><br>";
			echo "<b><h2 class=nick>".$r2['nickname']."</h2></b>";
			echo '<span class=ms>'.mb_substr($r['message'], 0, 30).'</span>';
			echo "</div>";
			echo '</a>';

64145322c9570242329489.png
  • Вопрос задан
  • 73 просмотра
Пригласить эксперта
Ответы на вопрос 2
yotaartist
@yotaartist
PHP Dev
Какая гадость эта ваша заливная рыба... Очень странно видеть вывод разметки через пыху, конечно, но дело не моё.
Для начала - никогда не используй query(), используй плейсхолдеры ($db->prepare(твой сикуэль запрос, при этом все значения, вставляемые извне замени на ? (знак вопроса для чайников)); $db->execute([а тут перечисляй вставляемые значения по порядку]);
Убережешь себя от инъекций.
Соответственно, фетчить так - тоже не выход, старовато. Юзай $msg->fetchAll() для выбора ВСЕХ подходящих по условию строк (либо fetch() для одной первой попавшейся по условию строки). Ну а там уже можно и мозгами пораскинуть, куда что и как подставлять.
Ответ написан
Комментировать
@alexalexes
Чтобы выдернуть по одному сообщению от каждого пользователя, нужно проранжировать сообщения особым счетчиком с подзапросом, имитирующим оконную функцию row_number.
select a.*
  from (select m.*, u.*, count(select *
                                              from messages as m2
                                                join users as u2 on u2.id = m2.author
                                            where m2.recipient = 1
                                                and u2.id = u.id -- имитация клаузы partition by
                                                and m2.id > m.id -- имитация клаузы order by  ... desc
                               ) as row_num, -- аналог row_number через оконную функцию:
                             -- row_number() over(partition by u.id order by m.id desc) as row_num 
  from messages as m
   join users as u on u.id = m.author
where m.recipient = 1
) as a
where a.row_num = 1 -- берем 1 строку по ранжированному счетчику в пределах каждого id пользователя
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы