Запрос, чтобы получить только одну строку из нескольких строк, имеющих одинаковые значения

У меня есть таблица уведомлений следующим образом

|id|user_receiver|user_sender|post_id|action|date|is_read

Вот user_sender это человек, который сгенерировал уведомление, user_receiver тот, кто получил уведомление, post_id это идентификатор сообщения, action может быть как, комментировать и т. д., is_read равен 1, если его читает получатель, иначе 0

Я хочу получать все уведомления для авторизованного пользователя

запрос, который я использую,

SELECT id, user_receiver, user_sender, post_id, action, 
 max(date) as date, is_read 
FROM notification 
WHERE user_receiver=$ses_user 
group by user_sender, action,post_id,is_read 
order by date desc

но это не дает мне последние строки, хотя я использую max(date) и я также хочу получить количество непрочитанных уведомлений.

Я хочу только одну строку, если есть несколько строк, имеющих одинаковые post_id, user_sender и action вместе, и это должно быть самое последнее. Например, пользователю нравится сообщение, строка добавляется в таблицу, затем пользователю не нравится и снова нравится, затем снова добавляется новая строка, я хочу только новую строку.

2 ответа

Решение

Чтобы получить последнюю строку в MySQL, вам нужно использовать join или коррелированный подзапрос:

SELECT id, user_receiver, user_sender, post_id, action, date, is_read
FROM notification n
WHERE user_receiver=$ses_user and
      date = (select max(date)
              from notification n2
              where n2.user_sender = n.user_sender and
                    n2.action = n.action and
                    n2.post_id = n.post_id and
                    n2.is_read = n.is_read
             )
order by date desc;

В других базах данных вы просто используете row_number() функция (или distinct on в Postgres).

РЕДАКТИРОВАТЬ:

Для самого большого идентификатора:

SELECT id, user_receiver, user_sender, post_id, action, date, is_read
FROM notification n
WHERE user_receiver=$ses_user and
      id   = (select max(id)
              from notification n2
              where n2.user_sender = n.user_sender and
                    n2.action = n.action and
                    n2.post_id = n.post_id
             )
order by date desc;

Если вы хотите количество строк, где isread = 1тогда вы можете сделать что-то вроде:

SELECT sum(is_read = 1)
FROM notification n
WHERE user_receiver=$ses_user and
      id   = (select max(id)
              from notification n2
              where n2.user_sender = n.user_sender and
                    n2.action = n.action and
                    n2.post_id = n.post_id
             );

Надеюсь, этот пост поможет, есть пример запроса с иллюстрацией:

SELECT 
    BookId, 
    BookName, 
    BookCategory, 
    BookReferenceNumber, 
    COUNT( BookReferenceNumber ) AS HowManyRecs, 
    BookDetails, 
    BookStatus
FROM 
    tbl_BOOKS
WHERE (
    BookReferenceNumber LIKE '42324%'
    OR BookName LIKE '%42324%'
)    
AND (
    BookStatus = 'Available'
)
GROUP BY 
    BookReferenceNumber
HAVING (
    HowManyRecs > 0
)

(Взято с techqube.blogspot.in)

Другие вопросы по тегам