2013-12-09 105 views
6

熟悉的問題,但使用Vertica。我想根據每個tag_id的sum(imps)返回前5個geo_country行。這是我開始的查詢:返回每組最多N行(Vertica/vsql)

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)值足夠高,應該將其包含在結果中。

另外,如何實現Top N部分?我試圖在OVER函數中添加一個LIMIT子句,但它看起來並不像一個可接受的參數。

回答

9

已解決。該解決方案是將查詢轉換爲子查詢,然後使用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; 
+0

這是我每次使用的模式,但由於某種原因,它是如此令人不滿意。我想我希望有一些類似於HAVING的分析查詢? – kimbo305

+1

考慮接受你的答案來完成問題。 – Kermit

+0

@ kimbo305這不是分析查詢如何工作,也不會遵循SQL標準。 – Kermit

0

我覺得這裏發生了什麼是組通過您的訂單上TAG_ID然後GEO_COUNTRY數據。做一個限制然後取前10條記錄。如果tag_id 1至少有10個geo_countries,則只能在結果中看到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;