J'essaie d'interroger ma base de données postgresql pour renvoyer des résultats contenant une date correspondant à un mois et à une année donnés. En d'autres termes, je voudrais toutes les valeurs pour un mois-année.
La seule façon dont j'ai pu le faire jusqu'à présent est la suivante:
SELECT user_id
FROM user_logs
WHERE login_date BETWEEN '2014-02-01' AND '2014-02-28'
Le problème avec ceci est que je dois calculer la première date et la dernière date avant d'interroger la table. Y a-t-il un moyen plus simple de faire cela?
Merci
Avec les dates (et les heures), beaucoup de choses deviennent plus simples si vous utilisez >= start AND < end
.
Par exemple:
SELECT
user_id
FROM
user_logs
WHERE
login_date >= '2014-02-01'
AND login_date < '2014-03-01'
Dans ce cas, vous devez toujours calculer la date de début du mois dont vous avez besoin, mais celle-ci doit être simple, de plusieurs manières.
La date de fin est également simplifiée; il suffit d'ajouter exactement un mois. Pas de déconner avec les 28, 30, 31, etc.
Cette structure présente également l’avantage de pouvoir conserver l’utilisation des index.
Beaucoup de gens peuvent suggérer un formulaire tel que le suivant, mais ils () ne le font pas utilisent les index:
WHERE
DATEPART('year', login_date) = 2014
AND DATEPART('month', login_date) = 2
Cela implique de calculer les conditions pour chaque ligne de la table (un balayage) et de ne pas utiliser d'index pour trouver la plage de lignes qui correspondra (une recherche de plage).
Depuis PostgreSQL 9.2 Les types de plages sont supportés. Donc, vous pouvez écrire ceci comme:
SELECT user_id
FROM user_logs
WHERE '[2014-02-01, 2014-03-01]'::daterange @> login_date
cela devrait être plus efficace que la comparaison de chaînes
Juste au cas où quelqu'un atterrirait ici ... depuis 8.1, vous pouvez simplement utiliser:
SELECT user_id
FROM user_logs
WHERE login_date BETWEEN SYMMETRIC '2014-02-01' AND '2014-02-28'
De la docs:
ENTRE SYMETRIQUE est identique a ENTREE sauf qu'il n'est pas nécessaire que l'argument situé à gauche de AND soit inférieur ou égal à l'argument situé à droite. Si ce n'est pas le cas, ces deux arguments sont automatiquement échangés, de sorte qu'une plage non vide est toujours implicite.