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

Primeiro e último valor da função de janela em uma linha no PostgreSQL


A pergunta é antiga, mas esta solução é mais simples e rápida do que o que foi postado até agora:
SELECT b.machine_id
     , batch
     , timestamp_sta
     , timestamp_stp
     , min(timestamp_sta) OVER w AS batch_start
     , max(timestamp_stp) OVER w AS batch_end
FROM   db_data.sta_stp a
JOIN   db_data.ll_lu   b ON a.ll_lu_id = b.id
WINDOW w AS (PARTITION BY batch, b.machine_id) -- No ORDER BY !
ORDER  BY timestamp_sta, batch, machine_id; -- why this ORDER BY?

Se você adicionar ORDER BY para a definição do quadro da janela, cada linha seguinte com um ORDER BY maior expressão tem um início de quadro posterior. Nem min() nem first_value() pode retornar o "primeiro" timestamp para toda a partição então. Sem ORDER BY todas as linhas da mesma partição são pares e você obtém o resultado desejado.

Seu ORDER BY adicionado funciona (não o da definição do quadro da janela, o externo), mas não parece fazer sentido e torna a consulta mais cara. Você provavelmente deve usar um ORDER BY cláusula que concorda com a definição do seu quadro de janela para evitar custos adicionais de classificação:
... 
ORDER BY batch, b.machine_id, timestamp_sta, timestamp_stp;

Não vejo necessidade de DISTINCT nesta consulta. Você pode simplesmente adicioná-lo se realmente precisar. Ou DISTINCT ON () . Mas então o ORDER BY cláusula torna-se ainda mais relevante. Ver:

Se você precisar de outra(s) coluna(s) da mesma linha (enquanto ainda classifica por timestamps), sua ideia com FIRST_VALUE() e LAST_VALUE() pode ser o caminho a seguir. Você provavelmente precisará anexar isso à definição do quadro da janela então :
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING

Ver: