PostgreSQL: jours / mois / années entre deux dates
Je cherche un moyen d'implémenter la fonction SQLServer datediff dans PostgreSQL. C'est-à-dire
datediff(dd, '2010-04-01', '2012-03-05') = 704 // 704 changes of day in this interval
datediff(mm, '2010-04-01', '2012-03-05') = 23 // 23 changes of month
datediff(yy, '2010-04-01', '2012-03-05') = 2 // 2 changes of year
Je sais que je pourrais faire ' dd ' en utilisant simplement la soustraction,mais une idée sur les deux autres?
6 réponses
Essayez quelque chose comme:
select age('2010-04-01', '2012-03-05'),
date_part('year',age('2010-04-01', '2012-03-05')),
date_part('month',age('2010-04-01', '2012-03-05')),
date_part('day',age('2010-04-01', '2012-03-05'));
Cette fonction vous donnera complète années, mois, jours ... entre les deux dates. Pour le nombre de changements de date - nous le lien fourni par revoua : http://www.sqlines.com/postgresql/how-to/datediff
Soustrayez-les simplement:
select '2015-01-12'::date - '2015-01-01'::date;
Cela vous donnera:
?column?
----------
11
J'ai passé du temps à chercher la meilleure réponse, et je pense que je l'ai.
Ce sql vous donnera le nombre de jours entre deux dates integer
:
SELECT
(EXTRACT(epoch from age('2017-6-15', now())) / 86400)::int
..qui, lorsqu'il est exécuté aujourd'hui (2017-3-28
) me donne:
?column?
------------
77
L'idée fausse sur la réponse acceptée:
select age('2010-04-01', '2012-03-05'),
date_part('year',age('2010-04-01', '2012-03-05')),
date_part('month',age('2010-04-01', '2012-03-05')),
date_part('day',age('2010-04-01', '2012-03-05'));
.. est-ce que vous obtiendrez la différence littérale entre les parties des chaînes de date, pas le temps entre les deux dates.
I. E:
Age(interval)=-1 years -11 mons -4 days;
Years(double precision)=-1;
Months(double precision)=-11;
Days(double precision)=-4;
Presque la même fonction que vous aviez besoin (basé sur la réponse d'atiruz, version raccourcie D'UDF de ici)
CREATE OR REPLACE FUNCTION datediff(type VARCHAR, date_from DATE, date_to DATE) RETURNS INTEGER LANGUAGE plpgsql
AS
$$
DECLARE age INTERVAL;
BEGIN
age := age(date_to, date_from);
CASE type
WHEN 'month' THEN
RETURN date_part('year', age) * 12 + date_part('month', age);
WHEN 'year' THEN
RETURN date_part('year', age);
ELSE
RETURN (date_to - date_from)::int;
END CASE;
END;
$$;
Utilisation:
/* Get months count between two dates */
SELECT datediff('month', '2015-02-14', '2016-01-03');
/* Get complete years count between two dates */
SELECT datediff('year', '2015-02-14', '2016-01-03');
/* Get days count between two dates */
SELECT datediff('day', '2015-02-14', '2016-01-03');
/* Get months count between specified and current date */
SELECT datediff('month', '2015-02-14', NOW()::date);
SELECT date_part ('year', f) * 12
+ date_part ('month', f)
FROM age ('2015-06-12'::DATE, '2014-12-01'::DATE) f
Résultat: 6
Voici un exemple complet avec la sortie. psql (10.1, serveur 9.5.10).
Vous obtenez 58, pas une valeur inférieure à 30.
Supprimer la fonction age (), résolu le problème que le post précédent mentionné.
drop table t;
create table t(
d1 date
);
insert into t values(current_date - interval '58 day');
select d1
, current_timestamp - d1::timestamp date_diff
, date_part('day', current_timestamp - d1::timestamp)
from t;
d1 | date_diff | date_part
------------+-------------------------+-----------
2018-05-21 | 58 days 21:41:07.992731 | 58