Si vous cherchez à générer une série chronologique, consultez cette question
Disons que je veux générer une série de dates entre deux dates. Je vois la fonction generate_series
fournit uniquement
Function Argument Type Return Type Description
generate_series(start, stop, step interval) timestamp or timestamp with time zone setof timestamp or setof timestamp with time zone (same as argument type) Generate a series of values, from start to stop with a step size of step
Alors, comment pourrais-je faire cela?
Vous pouvez utiliser generate_series
Pour cela, mais assurez-vous de convertir explicitement les arguments en "horodatage sans fuseau horaire" sinon ils seront par défaut msgstr "horodatage avec fuseau horaire". PostgreSQL surcharge generate_series
Pour les deux entrées.
timestamp with timezone
Vous pouvez voir l'inconvénient ici.
SET timezone = 'America/Santiago';
SELECT generate_series(date '2016-08-15', date '2016-08-15', '1 day');
SELECT generate_series(date '2016-08-14', date '2016-08-15', '1 day');
Les deux ci-dessus renvoient le même nombre de jours. Vous pouvez le voir à nouveau ici.
SET timezone = 'America/Sao_Paulo';
SELECT generate_series(date '2016-10-16', date '2016-10-17', '1 day');
SELECT generate_series(date '2016-10-17', date '2016-10-17', '1 day');
Ce qui précède montre deux plages d'une journée.
La raison de ce comportement est que ces fuseaux horaires ont leur "limite DST à minuit, plutôt qu'une heure plus sensible aux petites heures"
Alors à quoi ça ressemble de "bien faire",
SELECT generate_series(
timestamp without time zone '2016-10-16',
timestamp without time zone '2016-10-17',
'1 day'
);
Maintenant, vous pouvez diffuser à ce jour ..
SELECT d::date
FROM generate_series(
timestamp without time zone '2016-10-16',
timestamp without time zone '2016-10-17',
'1 day'
) AS gs(d);
Cette question et réponse a été inspirée par une conversation avec RhodiumToad sur IRC (irc: //irc.freenode.net/#postgresql). Il m'a modifié pour ce problème et a fourni le solution.
generate_series(date,date,interval)
En jouant, j'ai découvert que je pourrais peut-être éviter d'avoir à transposer explicitement dans timestamp without time zone
En surchargeant generate_series(date,date,interval)
Voici ma fonction,
CREATE FUNCTION generate_series( t1 date, t2 date, i interval )
RETURNS setof date
AS $$
SELECT d::date
FROM generate_series(
t1::timestamp without time zone,
t2::timestamp without time zone,
i
)
AS gs(d)
$$
LANGUAGE sql
IMMUTABLE;
Maintenant, je peux relancer le cas de test ci-dessus et ce n'est plus louche. Ces deux retournent tous les deux la même chose,
SET timezone = 'America/Santiago';
SELECT d::date
FROM generate_series(date '2016-08-15', date '2016-08-15', '1 day')
AS gs(d);
SELECT d::date
FROM generate_series(
timestamp without time zone '2016-08-15',
timestamp without time zone '2016-08-15',
'1 day'
)
AS gs(d);
Comme ces deux-là,
SELECT d::date
FROM generate_series(date '2016-08-14', date '2016-08-15', '1 day')
AS gs(d);
SELECT d::date
FROM generate_series(
timestamp without time zone '2016-08-14',
timestamp without time zone '2016-08-15',
'1 day'
)
AS gs(d);
generate_series(date,date,int)
Une autre option est de créer une nouvelle fonction generate_series(date,date,int)
cependant vous ne pouvez pas avoir les deux pour les raisons mentionnées ici . Alors choisissez-en un,
generate_series(date,date,interval)
generate_series(date,date,int)
Si vous voulez la deuxième option, essayez celle-ci:
CREATE FUNCTION generate_series( t1 date, t2 date, i int )
RETURNS setof date
AS $$
SELECT d::date
FROM generate_series(
t1::timestamp without time zone,
t2::timestamp without time zone,
i * interval '1 day'
)
AS gs(d)
$$
LANGUAGE sql
IMMUTABLE;
Avec l'examen sur irc, il y a quelques problèmes avec ces idées,
<johto>
generate_series(date, date, unknown)
fonctionne déjà aujourd'hui. lorsque vous ne le cassez pas avec la version int (par exemplegenerate_series(date, date, '1 day')
), vous changez le type de retour de timestamptz à date.(date, date, interval)
Casserait moins de cas, mais vous changeriez quand même le type de sortie. (il n'est pas non plus évident de savoir ce qui devrait arriver avec(date, date, '1 hour')
qui "fonctionne" actuellement très bien)