Isso apareceu algumas vezes, por exemplo, no grupo de notícias postgresql e no wiki . Em geral, a relação entre diferentes interval
s pode não ser bem definida - um mês pode ter diferentes números de dias, dependendo de qual mês (e ano) está sendo considerado. Mas às vezes é necessário calcular quantos intervalos ocorrem entre dois pontos no tempo, por exemplo (exemplo simplificado):
CREATE TABLE recordings(tstart timestamp, tend timestamp, interval ticklength);
SELECT (tend - tstart) / ticklength AS numticks
FROM recordings;
Isso não é permitido no PostgreSQL porque é uma divisão entre dois intervalos, que não teria um comportamento geral bem definido pelos motivos acima. Existe uma solução alternativa para quando um intervalo pode ser convertido em segundos, mas qual é a melhor maneira quando não é o caso, por exemplo, quando o intervalo é da ordem de milissegundos?
Como @a_horse_with_no_name menciona em seu comentário, a divisão pode ser obtida pela conversão em milissegundos.
A solução alternativa à qual você vincula (extrair épocas dos intervalos e dividir por eles) funciona bem para segundos e milissegundos. Portanto, se esse for o seu caso de uso, use-o.
Se você quiser ser mais geral e retornar NULL quando nenhuma resposta for possível, porém, temos que ser mais complexos:
Embora, por enquanto, o Postgres não pareça suportar divisão de intervalo, é claro que você pode converter esses intervalos em um número que pode dividir - como segundos.
As outras respostas propostas sugerem:
EXTRACT(MILLISECOND FROM interval '1 day')
, mas descobri que isso às vezes retorna0
. E, claro, não se pode dividir por zero.Mas o seguinte funciona muito melhor e é mais confiável:
Então, para dividir intervalos - extraia o número de segundos no intervalo usando
EXTRACT(EPOCH, interval)
e divida-os.A resposta aceita está errada.
Não acho que você deva adicionar os milissegundos de extração do intervalo, pois a época de extração do intervalo já extrai segundos com milissegundos. A documentação diz:
Você pode experimentar:
você vê como o ".123" aqui nos diz que os milissegundos já foram incluídos?
Acho que já passou da hora de adicionar o operador de divisão para intervalos.
E com isso:
Algumas ressalvas:
Ano juliano, mas não um mês juliano médio.