web-dev-qa-db-fra.com

Soustraction d'un jour à une date d'horodatage

J'utilise Datagrip pour Postgresql. J'ai une table avec un champ de date au format timestamp (ex: 2016-11-01 00:00:00). Je veux pouvoir:

  1. appliquer un opérateur mathématique pour soustraire 1 jour
  2. filtrez-le en fonction d'une fenêtre temporelle d'aujourd'hui-130 jours
  3. l'afficher sans la partie hh/mm/ss du tampon (2016-10-31)

Requête de départ actuelle:

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

La clause ((date_at)-1) sur la ligne 1 a pour résultat:

[42883] ERREUR: l'opérateur n'existe pas: horodatage sans fuseau horaire - entier Indice: aucun opérateur ne correspond au nom et au type d'argument donnés. Vous devrez peut-être ajouter des conversions de type explicites. Position: 69

La clause now() génère un message similaire:

[42883] ERREUR: l'opérateur n'existe pas: horodatage avec fuseau horaire - entier Indice: aucun opérateur ne correspond au nom et au type d'argument donnés. Vous devrez peut-être ajouter des conversions de type explicites. Position: ...

Les guides en ligne pour les transtypages sont particulièrement inutiles. L'entrée est appréciée.

41
J-Ko

Utilisez le type INTERVAL. Par exemple:

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

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

Ensuite, vous pouvez effectuer les opérations suivantes sur votre requête:

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;

Conseil additionnel¹

Vous pouvez ajouter plusieurs opérandes. Ex .: Comment obtenir le dernier jour du mois en cours?

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

Conseil additionnel²

Vous pouvez également créer un intervalle à l'aide de la fonction make_interval, utile lorsque vous devez le créer au moment de l'exécution (sans utiliser de littéraux):

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

Plus d'infos ici et ici .

100
Michel Milezzi