14:18 

Группировка + сортировка как?

Plexx
Имеем таблицу
id user_id date text
1 | 1 | 14-09-2012 15-00 | бла бла
2 | 2 | 14-09-2012 16-00 | бла бла
3 | 1 | 14-09-2012 17-00 | бла бла
4 | 2 | 14-09-2012 18-00 | бла бла

Нужно получить результат

4 | 2 | 14-09-2012 18-00 | бла бла
3 | 1 | 14-09-2012 17-00 | бла бла

Как?

При группировке и последующей сортировке выводит не правильно. А точнее самые первые по дате.

@темы: MySQL, Вопросы

Комментарии
2012-09-14 в 14:33 

Urban knight
But there’s no sense crying over every mistake. You just keep on trying till you run out of cake.
нужно два последних?

2012-09-14 в 15:36 

Plexx
Не два последних а все записи сгруппированные по user_id и отсортированые по дате.

2012-09-14 в 18:16 

Plexx
Сделал так.

SELECT * FROM comments WHERE date>NOW() - INTERVAL 1 DAY GROUP BY user_id ORDER BY MAX(date) ASC

поправьте если не правильно.

2012-09-14 в 23:16 

--==SS==--
Sanctus Satanas
Plexx, задача вывести последние по дате записи для каждого пользователя?
Ну подробно эта проблема описана, например, здесь: www.artfulsoftware.com/infotree/mysqlquerytree.... (Aggregates -> Within-group aggregates)

Вкратце, основные решения такие:
1) коррелированный подзапрос
SELECT *
FROM   comments AS c1
WHERE  c1.date = (SELECT Max(c2.date)
                  FROM   comments AS c2
                  WHERE  c2.user_id = c1.user_id);


2) join сгруппированной временной таблицы
SELECT c.*
FROM   comments AS c
       JOIN (SELECT user_id,
                    Max(date) AS max_date
             FROM   comments
             GROUP  BY user_id) AS t
         ON c.user_id = t.user_id
            AND c.date = t.max_date;


3) left join самой себя с отсечением по макс. дате
SELECT c1.*
FROM   comments AS c1
       LEFT JOIN comments AS c2
              ON c2.user_id = c1.user_id
                 AND c2.date > c1.date
WHERE  c2.user_id IS NULL;


4) группировка отсортированной временной таблицы
SELECT *
FROM   (SELECT *
        FROM   comments
        ORDER  BY date DESC) AS t
GROUP  BY t.user_id; 

2012-09-15 в 11:50 

Plexx
SS а то что я показал почему нельзя? вроде работает и правильно выводит.

2012-09-15 в 17:18 

--==SS==--
Sanctus Satanas
Plexx, потому что ты фигню написал. У тебя идёт выборка записей, дата и время которых больше, чем день назад от текущего момента (записи за позавчера вообще игнорируются), затем группируется по user_id (MySQL в этом случае обычно берёт записи, первые попавшиеся под руку), а затем результат зачем-то сортируется по тому, какому user_id соответствует максимальная дата среди всей выборки до группировки. Смысл всех этих действий от меня ускользает. А что такое «работает» я вообще не понимаю: оно на твоём же примере не даёт ожидаемый результат.
Я привёл примеры, как можно решить задачу «выбрать для каждого user_id по одной записи, имеющей максимальную дату среди всей таблицы». При этом физический порядок записей в базе, сегодняшняя дата и положение звёзд на небе не имеют никакого значения. Если это не то, что на самом деле требовалось — могу только посоветовать писать задачу точнее. )

2012-09-16 в 13:29 

Plexx
SS не не.. все ок.. Протестировав оно так и получилось как Вы сказали. Взял на заметку.
Использовал коррелированный подзапрос. Спасибо за помощь.

2012-09-16 в 16:19 

--==SS==--
Sanctus Satanas
Plexx, ок. Тогда ещё один момент насчёт, собственно, скорости работы этих запросов. В принципе, самым медленным вариантом должен быть как раз первый, а довольно интересным — четвёртый... Но все их можно существенно ускорить, правильно расставив индексы. Так, если на скорую руку, то:
1—3 варианты — составной по (`user_id`, `date`), можно уникальный;
4 вариант — `date`, неуникальный.
По-хорошему, конечно, надо брать реальные данные, смотреть EXPLAIN и замерять. А ещё учесть, что на разном числе записей результаты могут различаться.

   

Сообщество PHP программистов

главная