2009-06-02 6 views
5

У меня есть запрос, который делает ряд объединений и имеет несколько критериев в ИНЕКЕ, и я в конечном итоге с результатом, который по существу выглядит следующим образом:SQL группа по проблеме

| userId |  date | otherData | 
|--------+------------+------------| 
|  1 | 2008-01-01 | different | 
|  1 | 2009-01-01 |  info | 
|  1 | 2010-01-01 |  for | 
|  2 | 2008-01-01 |  each | 
|  3 | 2008-01-01 |  row | 
|  3 | 2009-01-01 |  here | 

Так , по сути для каждого пользователя, в прошлом будет одна или несколько дат и 0 или более дат в будущем.

Мне нужно как-то уменьшить набор данных до одной строки для каждого пользователя, только выбрать строку, которая имеет самую последнюю прошедшую дату. То есть, с тем, что магией GROUP BY или HAVING пунктом добавлен, результат выше будет выглядеть следующим образом:

| userId |  date | otherData | 
|--------+------------+------------| 
|  1 | 2009-01-01 |  info | 
|  2 | 2008-01-01 |  each | 
|  3 | 2009-01-01 |  here | 

ответ

5

Я думаю, что вы не хотите использовать GROUP BY/HAVING, потому что вы заинтересованы в точности 1 ряд на пользователя, и эта строка уже существует в таблице как есть. Это требует предложения WHERE, а не GROUP BY/HAVING.

Мое предложение состоит в том, что в предложении WHERE вы добавляете условие, что дата должна быть равна результату подзапроса. Этот подзапрос должен:

  1. Выберите макс (дата)
  2. Есть ИНЕКЕ, что ограничивает срок будет меньше, чем сейчас
  3. Есть ИНЕКЕ с UserID равно идентификатор пользователя внешнего запроса в

Чтобы предотвратить случаи, когда определенный пользователь может иметь две записи с той же датой, которая также является максимальной «прошедшей» датой, вы также должны добавить DISTINCT.

Надеюсь, что это поможет.

+0

хорошо работает !! но добавив DISTINCT, не удаляя повторяющиеся значения, любое предложение? – Rakesh

0

Как это:

select a.userId, a.date, b.userId, b.otherData 
from table1 as a 
left outer join table2 as b on a.userId = b.userId 
where b.Id in (
    select top 1 Id from table2 as c where c.userId = a.userId) 
0
 
Select 
    userID, date, otherData 
from 
    yourTable t1 
where 
    date = 
    (select max(date) from yourTable t2 
    where t1.userID=t2.userID) 
0
select T.userid, T.date, T.otherdata 
from 
    T, 
    (select userid, max(date) max_date from T group by userid) GT 
where 
    T.userid = GT.userid and T.date = GT.max_date 

Объяснение: Внутренний выбор - izolate только записи с датой максимальной для каждого пользователя. весь выбор - присоедините отобранные записи с исходной таблицей, чтобы получить поле otherdata.

Я предположил, что для идентификатора пользователя существует только одна максимальная дата. Скажите, если это правильное предположение.

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