2016-05-05 2 views
0

Я использую mysql.MySQL: ВЫБРАТЬ всех пользователей с 5 нераспечатанными сообщениями в последних 5 сообщениях, полученных в таблице сообщений

У меня есть таблица сообщений с идентификатором пользователя, message_id, открытым (истинным или ложным), меткой времени.

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

Это то, что я прямо сейчас:

SELECT mnc.userid 
FROM `messages` mnc 
WHERE (select count(*) from messagesas m where m.userid = mnc.userid 
     and m.message_sendtime_timestamp >= mnc.message_sendtime_timestamp 
    and m.opened = 'FALSE') >= 6 

Но это дает мне пользователей с более чем 6 неоткрыто Сообщения не обязательно последовательных

Здесь приведены примеры данных

CREATE TABLE messages 
    (`user_id` int, `timestamp` datetime, `opened` varchar(5)) 
; 

INSERT INTO messages 
    (`user_id`, `timestamp`, `opened`) 
VALUES 
    (1, '2016-01-01 00:00:00', 'false'), 
    (1, '2016-02-01 00:00:00', 'false'), 
    (1, '2016-03-01 00:00:00', 'false'), 
    (1, '2016-04-01 00:00:00', 'false'), 
    (1, '2016-05-01 00:00:00', 'false'), 
    (1, '2016-06-01 00:00:00', 'false'), 
    (2, '2016-01-01 00:00:00', 'false'), 
    (2, '2016-02-01 00:00:00', 'false'), 
    (2, '2016-03-01 00:00:00', 'false'), 
    (3, '2015-01-01 00:00:00', 'false'), 
    (3, '2016-01-01 00:00:00', 'false'), 
    (3, '2016-02-01 00:00:00', 'false'), 
    (3, '2016-03-01 00:00:00', 'false'), 
    (3, '2016-04-01 00:00:00', 'false'), 
    (3, '2016-05-01 00:00:00', 'true'), 
    (3, '2016-06-01 00:00:00', 'false'), 
    (4, '2015-01-01 00:00:00', 'true'), 
    (4, '2015-02-01 00:00:00', 'true'), 
    (4, '2016-01-01 00:00:00', 'false'), 
    (4, '2016-02-01 00:00:00', 'false'), 
    (4, '2016-03-01 00:00:00', 'false'), 
    (4, '2016-04-01 00:00:00', 'false'), 
    (4, '2016-05-01 00:00:00', 'false'), 
    (4, '2016-06-01 00:00:00', 'false') 

Ожидаемый результат:

userid 
1 
4 
+3

Покажите нам образец данных и ожидаемый результат. \t Пожалуйста, прочитайте [** How-to-Ask **] (http://stackoverflow.com/help/how-to-ask) \t \t И вот отличное место для [** START **] (http://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/), чтобы узнать, как улучшить качество вопроса и получить лучшие ответы. –

+0

Ваше имя говорит, что вы хотите получить последние 5 сообщений, в вопросе говорится, что вы хотите получить пользователей, которые не открывали ни одно из последних 5 сообщений. Что он? См. Http://stackoverflow.com/questions/2129693/mysql-using-limit-within-group-by-to-get-n-results-per-group для того, как сделать первый. Затем вы можете использовать это в подзапросе, чтобы проверить, открыто ли какое-либо из них. – Barmar

+0

@Barmar см. Редактировать – Simon

ответ

0
SELECT 
MAX(CASE WHEN (t.ct = 5 and t.op=5) THEN t.user_id END) AS userid 
FROM 
(
SELECT 
    user_id, 
    opened,timestamp , 
    @opened := opened, 
    IF ((@opened = 'false' && @prev = user_id) ,@o := @o + 1,@o := 1), 
    IF(@opened='true',@o:=0,@o) op, 

    IF (@prev = user_id ,@c := @c + 1,(@c := 1)) ct, 
    @prev := user_id 

FROM (SELECT @prev := 0 ,@c := 1,@opened :='0',@o := 0) var, 
messages 
order by user_id asc,timestamp desc 

) t 
GROUP BY t.user_id 

чек здесьhttp://sqlfiddle.com/#!9/8447a3/1

+0

Это, но для каждого оригинала в таблице – Simon

+0

Я не получил эту часть, какой смысл использовать orginalid? – Sachin

+0

Вы имеете в виду оригинал, как в оригинальной россыпке сообщения его идентификатор? a userId? – mitchken

0

, чтобы ответить на этот вопрос

Я хочу, чтобы все пользователи, которые не открыть сообщение в последних 5 сообщений, полученных?

Прежде всего, необходимо создать row_id для каждого user_id

SELECT @rowid := IF(@prev_value = user_id, @rowid + 1, 1) as row_id, 
     m.* 
     @prev_value := user_id 
FROM messages m, 
    (SELECT @row_num := 1) x, 
    (SELECT @prev_value := '') y 
ORDER BY `timestamp` DESC 

Затем проверьте, сколько открытое сообщение, которое вы имеете на этот подзапрос

SQL Fiddle Demo

SELECT user_id, COUNT(*), SUM(opened = 'false') 
FROM (
     SELECT @rowid := IF(@prev_value = user_id, @rowid + 1, 1) as row_id, 
       m.*, 
       @prev_value := user_id 
     FROM messages m, 
      (SELECT @row_num := 1) x, 
      (SELECT @prev_value := '') y 
     ORDER BY user_id, `timestamp` DESC 
    ) T 
WHERE row_id <= 5 -- only check last 5 or less messages 
GROUP BY user_id 
HAVING COUNT(*) = SUM(opened = 'false') -- Check all messages are NOT opened 
+0

Отлично. Я не уверен в НЕ открытой части. Я могу сделать это с моим col со значениями VAR TRUE или FALSE? – Simon

+0

какой тип поля ОТКРЫТО? –

+0

Его VAR. Должен ли я использовать что-то еще для улучшения запроса? – Simon

Смежные вопросы