J'ai été confronté à un scénario étrange lors de la comparaison entre les dates dans postgresql (version 9.2.4 sous Windows). J'ai une colonne dans ma table indiquant update_date avec le type «horodatage sans fuseau horaire». Le client peut effectuer une recherche dans ce champ avec uniquement la date (par exemple: 2013-05-03) ou la date avec l'heure (par exemple: 2013-05-03 12:20:00). Cette colonne a la valeur comme horodatage pour toutes les lignes actuellement et a la même partie de date (2013-05-03) mais une différence de temps.
Lorsque je compare sur cette colonne, j'obtiens des résultats différents. Comme les suivants:
select * from table where update_date >= '2013-05-03' AND update_date <= '2013-05-03' -> No results
select * from table where update_date >= '2013-05-03' AND update_date < '2013-05-03' -> No results
select * from table where update_date >= '2013-05-03' AND update_date <= '2013-05-04' -> results found
select * from table where update_date >= '2013-05-03' -> results found
Ma question est de savoir comment puis-je rendre la première requête possible pour obtenir des résultats, je veux dire pourquoi la troisième requête fonctionne mais pas la première?
la source
'2013-05-03'::date
et'1 day'::interval
) est-elle spécifique à PostgreSQL?CAST('2013-05-03' AS DATE) + CAST('1 day' AS INTERVAL)
(IIRC). YMMV sur l'existence et le comportement deDATE
etINTERVAL
.::DATE
ajout à la première partie de la clauseWHERE update_date::date = '2013-05-03'
fonctionnerait pas aussi bien et peut-être un peu plus lisible?update_date
c'étaittimestamp without timezone
. j'ai supposé un index sur cette colonne. votre prédicat n'utiliserait pas cet index.Lorsque vous comparez,
update_date >= '2013-05-03'
postgres convertit les valeurs dans le même type pour comparer les valeurs. Donc, votre '2013-05-03' a été casté dans '2013-05-03 00:00:00'.Donc, pour update_date = '2013-05-03 14:45:00' votre expression sera la suivante:
C'est toujours
false
Pour résoudre ce problème, lancez update_date sur
date
:select * from table where update_date::date >= '2013-05-03' AND update_date::date <= '2013-05-03' -> Will return result
la source
update_date
de la table par rapport à la conversion de la valeur unique du paramètre de requête est terriblement inefficace et garantit que le serveur ne pourra pas exploiter les index de cette colonne. je suis tenté de -1 ceci.SELECT * FROM my_table WHERE update_date >= '2013-05-03' AND update_date < '2013-05-04';
(Notez l'utilisation du 4 mai plutôt que 3ème et avec un SIGNE INFÉRIEUR plutôt que inférieur ou égal.)Utilisez le
range
type. Si l'utilisateur saisit une date:select * from table where update_date <@ tsrange('2013-05-03', '2013-05-03'::date + 1, '[)');
Si l'utilisateur entre des horodatages, vous n'avez pas besoin de la
::date + 1
piècehttp://www.postgresql.org/docs/9.2/static/rangetypes.html
http://www.postgresql.org/docs/9.2/static/functions-range.html
la source
Utilisez Date convert pour comparer avec la date: Essayez ceci:
select * from table where TO_DATE(to_char(timespanColumn,'YYYY-MM-DD'),'YYYY-MM-DD') = to_timestamp('2018-03-26', 'YYYY-MM-DD')
la source