Digamos que, para simplificar, eu tenha a seguinte tabela:
id amount p_id date
------------------------------------------------
1 5 1 2020-01-01T01:00:00
2 10 1 2020-01-01T01:10:00
3 15 2 2020-01-01T01:20:00
4 10 3 2020-01-01T03:30:00
5 10 4 2020-01-01T03:50:00
6 20 1 2020-01-01T03:40:00
Aqui está um exemplo de resposta que eu quero:
{
"2020-01-01T01:00:00": 25, -- this is from adding records with ids: 2 and 3
"2020-01-01T03:00:00": 55 -- this is from adding records with ids: 3,4,5 and 6
}
Eu quero obter o total ( sum(amount)
) de todos os exclusivos p_id
agrupados por hora.
A linha escolhida por p_id
é aquela com o último date
. Por exemplo, o primeiro valor na resposta acima não inclui id 1
porque o registro com id 2
tem o mesmo p_id
e o date
dessa linha é posterior.
A única coisa complicada é que eu quero incluir a soma de todos os amount
por p_id
se eles date
forem antes da hora apresentada. Por exemplo, no segundo valor da resposta (com a chave "2020-01-01T03:00:00"), embora id 3
tenha um carimbo de data/hora em uma hora diferente, é o mais recente para isso p_id 2
e, portanto, é incluído na soma de "2020-01-01T03:00:00". Mas a linha com id 6
substituições id 2
com o mesmo p_id 1
.
Em outras palavras: sempre pegue o último amount
para cada p_id
até o momento e calcule a soma para cada hora distinta encontrada na tabela.
Olhe para
Caso simples
Obter a soma para uma única hora é relativamente simples:
DISTINCT ON
normalmente é substancialmente mais rápido que a subconsulta/CTE comrow_number()
. Ver:Para muitas linhas por
p_id
, há potencial para otimizar um pouco mais com a indexação inteligente e uma consulta correspondente. Ver:Soma corrida especial para cada hora
Você parece querer a soma para cada hora distinta na tabela .
Você pode simplesmente destilar horas distintas e aplicar a solução simples a cada uma delas em uma
LATERAL
subconsulta:Deve ficar bem enquanto não há muitas horas distintas. Mas a consulta não escala muito bem . O último
amount
para cadap_id
é calculado com o custo total (aumentando continuamente) para cada hora adicional.Otimize a soma acumulada por muitas horas
Espero que esse CTE recursivo escale melhor (com uma sobrecarga considerável inicialmente), pois ele só precisa se unir a uma linha
p_id
a cada próxima hora:Além disso, pode haver mais potencial para otimizar, dependendo da distribuição de valor, como indicado para o caso simples no topo.
db<>fique aqui
Além disso: chamar sua
timestamp
coluna de "data" é bastante enganoso, pois é um tipo de dados básico diferente.