PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Obter a soma distinta de uma coluna de tabela unida


Para obter o resultado sem subconsulta , você deve recorrer a truques avançados de função de janela:
SELECT sum(count(*))       OVER () AS tickets_count
     , sum(min(a.revenue)) OVER () AS atendees_revenue
FROM   tickets   t
JOIN   attendees a ON a.id = t.attendee_id
GROUP  BY t.attendee_id
LIMIT  1;

sqlfiddle

Como funciona?


A chave para entender isso é a sequência de eventos na consulta:

funções agregadas -> funções de janela -> DISTINCT -> LIMIT

Mais detalhes:
  • Melhor maneira de obter a contagem de resultados antes da aplicação de LIMIT

Passo a passo:

  1. I GROUP BY t.attendee_id - o que você normalmente faria em uma subconsulta.

  2. Então eu somei as contagens para obter a contagem total de ingressos. Não muito eficiente, mas forçado por sua exigência. A função agregada count(*) é envolvido na função de janela sum( ... ) OVER () para chegar à expressão não tão comum:sum(count(*)) OVER () .

    E some a receita mínima por participante para obter a soma sem duplicatas.

    Você também pode usar max() ou avg() em vez de min() com o mesmo efeito que revenue é garantido para ser o mesmo para todas as linhas por participante.

    Isso poderia ser mais simples se DISTINCT era permitido em funções de janela, mas o PostgreSQL (ainda) não implementou esse recurso. Por documentação:

    Funções de janela agregadas, ao contrário das funções agregadas normais, não permitem DISTINCT ou ORDER BY para ser usado dentro da lista de argumentos da função.

  3. O passo final é obter uma única linha. Isso pode ser feito com DISTINCT (padrão SQL), pois todas as linhas são iguais. LIMIT 1 será mais rápido, no entanto. Ou o formulário padrão SQL FETCH FIRST 1 ROWS ONLY .