2013-12-09 17 views
6

Domanda familiare, ma con Vertica. Vorrei restituire le prime 5 righe geo_country in base alla somma (imp) per ogni tag_id. Questa è la query ho iniziato:Torna all'inizio N righe per ciascun gruppo (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; 

Ciò restituisce in realtà solo le righe dal primo tag nella clausola WHERE (2.013.150). So che l'altro tag ha valori di somma (imps) abbastanza alti che dovrebbero includerlo nei risultati.

Inoltre, come si implementa la parte Top N? Ho provato ad aggiungere una clausola LIMIT all'interno della funzione OVER, ma non sembra che sia un parametro accettato.

risposta

9

Risolto. La soluzione è quella di convertire la query a un subquery e quindi utilizzare la clausola WHERE per filtrare per Classifica:

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

Questo è lo schema che uso ogni volta, ma per qualche motivo è così insoddisfacente. Immagino che mi piacerebbe che ci fosse qualcosa di simile a HAVING per le query analitiche? – kimbo305

+1

Considera di accettare la tua risposta per completare la domanda. – Kermit

+0

@ kimbo305 non è così che funzionano le query analitiche né seguire gli standard SQL. – Kermit

0

Penso che quello che sta accadendo qui è che il gruppo da ordini I tuoi dati su tag_id e poi geo_country. Facendo un limite, prende i primi 10 record. Se ci sono almeno 10 account_google per tag_id 1, vedrai solo tag_id 1 nel tuo risultato. Non classificando sul grado ASC risolvi il tuo problema.

Non sono sicuro che l'uso del rango in un ordinamento sia consentito in 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; 
Problemi correlati