2015-02-27 5 views
0

У меня есть данные в таблице в следующем формате.SQL Выберите одну строку для каждого типа категории

id | person_id| category | value| updated_date 
----------------------------- 
1 | p1  |race | r1 | 2015-02-26 
2 | p1  |race | r2 | 2015-02-26 
3 | p2  |race | r3 | 2015-02-27 
4 | p2  | race | r1 | 2015-02-28 
5 | p1  | lang | l1 | 2015-02-26 

Теперь я фильтрую информацию о личности человека. Мне нужно следующее в наборе результатов.

  1. Мне нужна запись для каждой категории, которая существует для этого человека.
  2. Если существует несколько записей для категории, укажите один раз, который обновляется последним.
  3. Если обновленные даты совпадают, получите первый в списке.

Для p1,

1 | p1  |race | r1 | 2015-02-26 
5 | p1  | lang | l1 | 2015-02-26 
+0

Определение "первым в списке". SQL действительно не имеет понятия «порядок» как таковой, и полагаться на идентификаторы автогенераторов (если это то, что здесь означает 'id'), это не то, что вы обычно должны делать. Почему вы переключаетесь с самого недавно обновленного на раннее обновление? Или вы имели в виду раннее обновление в любом случае, и вам просто нужно более высокое разрешение на 'updated_date' (возможно, вы должны сделать это отметкой времени)? Это похоже на классическую проблему [tag: наибольшая n-на-группу], не отвечают ли стандартные ответы? –

ответ

0

Это что-то вроде этого. потому что id не является групповым полем, потому что он изменяется в каждой строке, вы выбираете min (id) для группы по personid, category, value.

select min(id), personid, category, value, max(updated_date) 
group by personid, category, value 
having Max(updated_date)  

/* min(id) is just to return the value of id 
for the row having max(update_date) 
having max(update_date) get's the highest date*/ 
0

Я предложил бы делать это с not exists:

select t.* 
from table t 
where not exists (select 1 
        from table t2 
        where t2.personid = t.personid and 
         t2.category = t.cateogory and 
         (t2.updated_date > t.updated_date or 
         t2.updated_date = t.updated_date and t2.id < t.id 
         ) 
       ); 
Смежные вопросы