Верните верхние n строк для каждой группы (Vertica/vsql)

знакомый вопрос, но с Vertica. Я хотел бы вернуть верхние 5 строк geo_country на основе sum (imps) для каждого tag_id. Это запрос, который я начал:

SELECT tag_id,
       geo_country,
       SUM(imps) AS imps,
       RANK() OVER (PARTITION BY tag_id ORDER BY SUM(imps) DESC) AS rank
FROM table1
WHERE tag_id IN (2013150,1981153)
AND ymd > CURRENT_DATE - 3
GROUP BY 1,
         2 LIMIT 10;

это фактически возвращает только строки из первого тега в предложении WHERE (2013150). Я знаю, что другой тег имеет значения sum(imps) достаточно высокие, которые должны включать его в результаты.

кроме того, как реализовать верхнюю часть N? Я попытался добавить предложение LIMIT в функцию OVER, но это не так похоже, это принятый параметр.

2 ответов


решена. Решение состоит в том, чтобы преобразовать запрос в подзапрос, а затем использовать предложение WHERE для фильтрации по рангу:

SELECT * 
FROM (SELECT tag_id, geo_country, sum(imps),
    RANK() OVER (PARTITION BY tag_id ORDER BY SUM(imps) DESC) AS rank 
    FROM table1
    WHERE tag_id IN (2013150,1981153)
    AND ymd > CURRENT_DATE - 3
    GROUP BY 1,2) as t2
WHERE t2.rank <=5;

Я думаю, что здесь происходит то, что группа по заказам ваши данные на tag_id, а затем geo_country. Выполнение ограничения затем занимает первые 10 записей. Если есть по крайней мере 10 geo_countries для tag_id 1, то вы увидите только tag_id 1 в своем результате. Сортировка по рангу ASC не решит вашу проблему.

Я не уверен, что использование ранга в сортировке разрешено, хотя в Vertica.

SELECT tag_id,
   geo_country,
   SUM(imps) AS imps,
   RANK() OVER (PARTITION BY tag_id ORDER BY SUM(imps) DESC) AS rank
FROM table1
WHERE tag_id IN (2013150,1981153)
AND ymd > CURRENT_DATE - 3
GROUP BY 1,
         2
ORDER BY 4
LIMIT 10;