2015-07-13 6 views
0

Учитывая схемувключают только первые и последние группы в результаты запроса

enter image description here

Следующий запрос

SELECT a.user_id, 
    a.id, 
    a.date_created, 
    avg(ai.level) level 
FROM assessment a 
    JOIN assessment_item ai ON a.id = ai.assessment_id 
GROUP BY a.user_id, a.id; 

Возвращает эти результаты

user_id, a.id, a.date_created,  level 
1,  99, "2015-07-13 18:26:00", 4.0000 
1,  98, "2015-07-13 19:04:58", 6.0000 
13,  9, "2015-07-13 18:26:00", 2.0000 
13,  11, "2015-07-13 19:04:58", 3.0000 

Я хотел бы изменить запрос, чтобы для каждого пользователя возвращались только самые ранние результаты. Другими словами, следующее должно быть возвращено вместо

user_id, a.id, a.date_created,  level 
1,  99, "2015-07-13 18:26:00", 4.0000 
13,  9, "2015-07-13 18:26:00", 2.0000 

Я думаю, что нужно добавить пункт HAVING, но я изо всех сил, чтобы выяснить точный синтаксис.

+0

является a.id уникальным в этой таблице? – dognose

+0

@dognose yes 'id' является первичным ключом в каждой таблице –

ответ

0

Я сделал что-то вроде этого, за исключением небольшой разницы, которую я хотел сначала по 5 на группу. Случай использования был для сообщения - значит, время для запуска запроса/создания таблицы temp не было ограничением.

Решения, которое я имел:

  • Создать новую таблицу со столбцами, как идентификатор (ссылка на исходную таблицу) и идентификатор может быть уникальными/первичным
  • ВСТАВИТЬ ИГНОРИРУЙТЕ НА tbl1 (ID) выберите мин (id) from original_tbl, где id не в (select id from tbl1) group by user_id
  • Повторите шаг 2 столько раз, сколько вам нужно (в моем случае это было 5 раз). новая таблица таблица будет иметь только идентификаторы, которые вы хотите показать
  • Теперь запустите объединение на tbl1 и исходной таблицы даст вам нужный результат

Примечание: Это может быть не лучшим решением, но это работает для меня, когда мне пришлось разделить отчет за 2-3 часа в выходные. И размер данных у меня было около 1 млн записей

0

Отказ от ответственности: Я в немного спешке, и не проверял это полностью

-- Create a CTE that holds the first and last date for each user_id. 
with first_and_last as (
    -- Get the first date (min) for each user_id 
    select a.[user_id], min(a.date_created) as date_created 
    from assessment as a 
    group by a.[user_id] 

    -- Combine the first and last, so each user_id should have two entries, even if they are the same one. 
    union all 

    -- Get the last date (max) for each user_id 
    select a.[user_id], max(a.date_created) 
    from assessment as a 
    group by a.[user_id] 
) 
select a.[user_id], 
     a.id, 
     a.date_created, 
     avg(ai.[level]) as [level] 
from assessment as a 
    inner join assessment_item as ai on a.id = ai.assessment_id 
    -- Join with the CTE to only keep records that have either the min or max date_created for each user_id. 
    inner join first_and_last as fnl on a.[user_id] = fnl.[user_id] and a.date_created = fnl.date_created 
group by a.[user_id], a.id, a.date_created; 
Смежные вопросы