Questo dovrebbe fare il trucco:
SELECT a
, sum(ab_ct)::int AS ct_total
, count(*)::int AS ct_distinct_b
, array_agg(b || ', ' || ab_ct::text) AS b_arr
FROM (
SELECT a, b, count(*) AS ab_ct
FROM tbl
GROUP BY a, b
ORDER BY a, ab_ct DESC, b -- append "b" to break ties in the count
) t
GROUP BY a
ORDER BY ct_total DESC;
Resi:
ct_total
:conteggio totale dib
pera
.ct_distinct_b
:conteggio dib
distinti pera
.b_arr
:matrice dib
più la frequenza dib
, ordinato per frequenza dib
.
Ordinato per conteggio totale di b
per a
.
In alternativa, puoi utilizzare un ORDER BY
clausola all'interno della chiamata aggregata
in PostgreSQL 9.0 o successivo. Come:
SELECT a
, sum(ab_ct)::int AS ct_total
, count(*)::int AS ct_distinct_b
, array_agg(b || ', ' || ab_ct::text ORDER BY a, ab_ct DESC, b) AS b_arr
FROM (
SELECT a, b, count(*) AS ab_ct
FROM tbl
GROUP BY a, b
) t
GROUP BY a
ORDER BY ct_total DESC;
Potrebbe essere più chiaro. Ma in genere è più lento. E l'ordinamento delle righe in una sottoquery funziona per query semplici come questa. Ulteriori spiegazioni: