Верните верхние 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;