2013-06-11 4 views
3

Если у меня есть таблица со следующей структурой и данными:Получение самую последнюю запись для каждого пользователя

id | user_id | created_at 
------------------------- 
1 |  7 | 0091942 
2 |  3 | 0000014 
3 |  6 | 0000890 
4 |  6 | 0029249 
5 |  7 | 0000049 
6 |  3 | 0005440 
7 |  9 | 0010108 

Что запрос я должен использовать, чтобы получить следующие результаты (объяснение следовать):

id | user_id | created_at 
------------------------- 
1 |  7 | 0091942 
6 |  3 | 0005440 
4 |  6 | 0029249 
7 |  9 | 0010108 

Как вы можете видеть:

  • только одна строка на user_id возвращается.
  • Вершина с самым высоким номером created_at.

Есть ли способ сделать это без с помощью подзапрограмм? Есть ли имя в языке реляционной алгебры, что эта процедура проходит?

+0

В SQL Server вы можете использовать функцию ранжирования 'row_number()', но, похоже, в MySql нет эквивалента: http://stackoverflow.com/questions/1895110/row-number-in -mysql – Blorgbeard

+0

Пожалуйста, не стесняйтесь публиковать решение на основе подзапроса, если вы хотите, чтобы я мог правильно его пометить. –

+0

, вы должны сменить столбец created_at на datetime, чтобы вы могли получить последнюю дату, о которой я думаю. –

ответ

6

Запрос известен как groupwise maximum, который (по крайней мере, в MySQL) может быть реализован с помощью подзапроса. Например:

SELECT my_table.* FROM my_table NATURAL JOIN (
    SELECT user_id, MAX(created_at) created_at 
    FROM  my_table 
    GROUP BY user_id 
) t 

См. Его на sqlfiddle.

+0

+1 для отображения NATURAL JOIN, для которого я никогда не видел использования (предпочитая явное соединение INNER). – BellevueBob

+1

+1 за правильный ответ. –

+0

+1 Используйте это вместо моего ответа. – isJustMe

2

Вы можете просто получить максимум и группы, по user_id:

select id,user_id,max(created_at) 
from supportContacts 
group by user_id 
order by id; 

Вот что он выводит:

ID USER_ID MAX(CREATED_AT) 
1 7 91942 
2 3 5440 
3 6 29249 
7 9 10108 

Смотрите рабочий demo here

Обратите внимание, что в примере на fiddle использует поле created_at как int, просто используйте ваш формат, и он не должен иметь никакого значения.

EDIT: Я оставлю этот ответ в качестве рефери, но обратите внимание, что его запрос приведет к нежелательным результатам, как заявил Гордон, пожалуйста, не используйте это в процессе производства.

+0

Интересно, SQL Server не позволит вам это сделать, поскольку 'id' не является частью' group by' и не агрегируется. – Blorgbeard

+0

Да, postgreSQL тоже не будет, к счастью, mysql. – isJustMe

+2

@isJustMe. , , Документация MySQL явно ясна, что результаты не определены («Сервер может выбирать любое значение из каждой группы, поэтому, если они не совпадают, выбранные значения являются неопределенными».). Вы можете прочитать документацию здесь: http://dev.mysql.com/doc/refman/5.5/ru/group-by-extensions.html. –

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