Subtraindo 1 dia de uma data de carimbo de data / hora

105

Estou usando o Datagrip para Postgresql. Eu tenho uma tabela com um campo de data no formato de carimbo de data / hora (ex: 2016-11-01 00:00:00). Eu quero ser capaz de:

  1. aplique um operador matemático para subtrair 1 dia
  2. filtrar com base em uma janela de tempo de hoje - 130 dias
  3. exibi-lo sem a parte hh / mm / ss do selo (2016-10-31)

Consulta inicial atual:

select org_id, count(accounts) as count, ((date_at) - 1) as dateat 
from sourcetable 
where  date_at <= now() - 130
group by org_id, dateat

A ((date_at)-1)cláusula na linha 1 resulta em:

[42883] ERRO: o operador não existe: carimbo de data / hora sem fuso horário - inteiro Dica: Nenhum operador corresponde ao nome e tipo (s) de argumento fornecidos. Pode ser necessário adicionar conversões de tipo explícitas. Cargo: 69

A now()cláusula gera uma mensagem semelhante:

[42883] ERROR: operador does not exist: timestamp with time zone - integer Dica: Nenhum operador corresponde ao nome e tipo de argumento fornecidos. Pode ser necessário adicionar conversões de tipo explícitas. Cargo: ...

Guias online para digitar moldes são particularmente inúteis. A entrada é apreciada.

J-Ko
fonte

Respostas:

239

Use o INTERVALtipo para isso. Por exemplo:

--yesterday
SELECT NOW() - INTERVAL '1 DAY';

--Unrelated to the question, but PostgreSQL also supports some shortcuts:
SELECT 'yesterday'::TIMESTAMP, 'tomorrow'::TIMESTAMP, 'allballs'::TIME;

Em seguida, você pode fazer o seguinte em sua consulta:

SELECT 
    org_id,
    count(accounts) AS COUNT,
    ((date_at) - INTERVAL '1 DAY') AS dateat
FROM 
    sourcetable
WHERE 
    date_at <= now() - INTERVAL '130 DAYS'
GROUP BY 
    org_id,
    dateat;


DICAS

Dica 1

Você pode anexar vários operandos. Ex: como obter o último dia do mês atual?

SELECT date_trunc('MONTH', CURRENT_DATE) + INTERVAL '1 MONTH - 1 DAY';

Dica 2

Você também pode criar um intervalo usando a make_intervalfunção, útil quando você precisa criá-lo em tempo de execução (não usando literais):

SELECT make_interval(days => 10 + 2);
SELECT make_interval(days => 1, hours => 2);
SELECT make_interval(0, 1, 0, 5, 0, 0, 0.0);


Mais informações:

Funções e operadores de data / hora

datatype-datetime (valores especiais) .

Michel Milezzi
fonte
2
Para aqueles que estavam se perguntando, "allballs" é um literal para meia-noite, porque parece 00:00:00.
wim