2015-05-27 3 views
0

У меня есть событие стол со следующими колонками user_id, points, created. То, что мне нужно, - это получить все очки за данный месяц, общее количество очков и общий ранг за заданные user_id. Мне нужно сделать это в одном запросе, который привел к следующей попытке:Производительность и вариации запросов PostgreSQL

select 
    e.user_id, 
    sum(e.points) as total_points, 
    (select sum(points) from event where user_id = 1 and extract(month from created) = 1) as month_points, 
    (select rank from (select user_id as id, rank() over (order by sum(points) desc) from event group by user_id) as rank where id = 1) 
from 
    event pte 
where 
    e.user_id = 1 
group by 
    e.user_id 
; 

То, что я хотел бы спросить:

  1. Может ли этот запрос быть медленным?
  2. Можно ли это сделать лучше/по-другому?
  3. rank Функция надежна или была неправильно использована?
+0

1) это будет очень быстро, потому что в нем содержится ошибка (в второй подзаголовок). 2) Да: исправить ошибку 3) зависит от намерения запроса – wildplasser

+0

@wildplasser, я обновил вопрос. – Opal

ответ

1

Предполагая PostGreSQL версии больше или равна 9.4, вы можете использовать совокупный filter положение, чтобы избежать подзапросов для month_points и rank:

select * from 
    (select 
     e.user_id, 
     sum(e.points) as total_points, 
     sum(points) filter (where extract(month from created) = 1) as month_points, 
     rank() over (order by sum(points) desc) 
    from 
     event e 
    group by 
     e.user_id 
    ) as inner_query 
where user_id = 1; 
+0

Помогает ли этот запрос работать лучше? Что делать, если я не могу использовать 9.4? – Opal

+0

'filter' не реализован в ранних версиях pg. Представление? Это зависит: если таблица 'event' мала или нет индекса в user_id, мой запрос должен работать лучше (но лучше проверить его самостоятельно). –

+0

Спасибо. Есть и индекс, это внешний ключ. – Opal

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