3 votes

L'opérateur BETWEEN de PostgreSQL se comporte différemment

J'ai utilisé une requête SQL pour extraire les données de quelques jours d'une solution déployée.

Et j'utilisais la requête de la manière suivante

select column1, column2, column3, column 4 
where <condition 1> AND <condition 2> AND 
      created_timestamp BETWEEN '05-31-2019' AND '06-11-2019'

Il récupérait les valeurs de toutes les colonnes et filtrait les données selon les conditions comme prévu, mais il y avait un problème. Il ne récupérait pas les données pour la date 11. th de juin qui est fourni comme limite supérieure.

D'après ce que je sais, un opérateur comprend les deux extrémités de la plage fournie.

Ce qui m'a troublé le plus, c'est qu'il incluait en quelque sorte les données de la date 31. st de mai qui est la limite supérieure.

  1. J'ai besoin de savoir si l'opérateur between (surtout dans postgresql, je ne pense pas que cela va changer, je veux juste confirmer) inclut ou non les points extrêmes de l'intervalle ?

  2. Même s'il inclut/exclut, il devrait se comporter de la même manière pour les deux points de terminaison. Je ne comprends pas le comportement biaisé. Quelqu'un a-t-il une idée à ce sujet ?

4voto

Tim Biegeleisen Points 53335

Essayez d'utiliser les littéraux de date appropriés :

SELECT column1, column2, column3, column4
FROM your_table
WHERE created_timestamp BETWEEN '2019-05-31' AND '2019-06-11';

2019-05-31 est au format ISO 8601, et signifie sans ambiguïté le 31 mai 2019 dans n'importe quel mode.

Vous pouvez en savoir plus sur les règles relatives aux types de date et d'heure. aquí .

Edit :

La raison pour laquelle les données du 11 juin n'apparaissent pas est que l'utilisation de la fonction 2011-06-11 comme limite supérieure de l'intervalle est identique à l'utilisation de 2011-06-11 00:00:00 . C'est-à-dire qu'il ne comprend que le 11 juin exactement à minuit. Pour atténuer ce problème, utilisez le 12 juin comme limite supérieure :

SELECT column1, column2, column3, column4
FROM your_table
WHERE created_timestamp >= '2019-05-31' AND created_timestamp < '2019-06-12';

1voto

Deepstop Points 3076

Si created_timestamp est une valeur de date/heure, plutôt qu'une simple date, alors tout ce qui se passera le 11 juin après minuit (00:00 heure) sera en dehors de l'intervalle BETWEEN. Vous pouvez donc faire ceci

date_trunc('day', created_timestamp) BETWEEN '2019-05-31' AND '2019-06-11'

Comme déjà indiqué, les dates doivent être au format aaaa-mm-jj. Il n'est pas nécessaire de les dater dans ce cas, comme l'a mentionné Gordon, mais il a raison de dire que, dans certaines situations, il est nécessaire de les dater et qu'il n'y a pas de mal à le faire.

1voto

Laurenz Albe Points 40920

Je suppose que created_timestamp est un timestamp (avec ou sans fuseau horaire).

Le littéral que vous avez utilisé, 06-11-2019 correspond à minuit à cette date :

SELECT '06-11-2019'::timestamp with time zone;
      timestamptz       
------------------------
 2019-06-11 00:00:00+02
(1 row)

Il n'est donc pas surprenant que les résultats n'incluent pas les données du 11 juin.

Il y a deux façons d'avancer :

  1. Utilisez le jour suivant et le < opérateur :

    ... WHERE created_timestamp >= '05-31-2019' AND created_timestamp < '06-12-2019'
  2. convertir l'horodatage en un date :

    ... WHERE date(created_timestamp) BETWEEN '05-31-2019' AND '06-11-2019'

La deuxième option ne peut pas utiliser un index sur created_timestamp (mais il peut utiliser un index sur date(created_timestamp) ).

Votre requête dépend de la configuration PostgreSQL de DateStyle Assurez-vous donc que ce paramètre est toujours celui dont vous avez besoin.

0voto

Gordon Linoff Points 213350

Sans doute, created_timestamp est en fait dans un format date/heure. Il faut donc comparer à des valeurs de date/heure, et non à des chaînes de caractères :

created_timestamp >= '2019-05-21'::date and
created_timestamp < '2019-06-11'::date

Notez que j'ai changé le between à deux inégalités. Cela signifie que les codes se comportent comme prévu lorsque created_timestamp a en fait une composante temporelle.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X