Maison >base de données >tutoriel mysql >Comment calculer les dates en ignorant l'année en SQL ?

Comment calculer les dates en ignorant l'année en SQL ?

DDD
DDDoriginal
2025-01-05 07:48:40136parcourir

How to Calculate Dates Ignoring the Year in SQL?

Comment effectuer des calculs de date qui ignorent l'année à l'aide de SQL

Problème :

Vous souhaitez sélectionner des dates qui ont un anniversaire dans les 14 prochains jours, mais vous souhaitez le faire en excluant l'année.

Exemple Requête :

SELECT *
FROM events
WHERE EXTRACT(month FROM "date") = 3
AND EXTRACT(day FROM "date") < EXTRACT(day FROM "date") + 14;

Défi :

La requête ci-dessus ne fonctionne pas car elle ne prend pas en compte l'effet de bouclage des mois.

Solutions :

1. Version avancée

Cette solution utilise une fonction SQL personnalisée et un index multicolonne pour des performances optimales.

CREATE OR REPLACE FUNCTION f_mmdd(date)
  RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT AS
'SELECT EXTRACT(month FROM )::int * 100 + EXTRACT(day FROM )::int';

CREATE INDEX event_mmdd_event_date_idx ON event(f_mmdd(event_date), event_date);

SELECT *
FROM event e
WHERE f_mmdd(e.event_date) BETWEEN f_mmdd(current_date)
                            AND f_mmdd(current_date + 14);

2. Fonction de table

Cette solution utilise une fonction de table PostgreSQL pour gérer le calcul de l'anniversaire.

CREATE OR REPLACE FUNCTION f_anniversary(_the_date date = current_date, _days int = 14)
  RETURNS SETOF event
  LANGUAGE plpgsql AS
$func$
DECLARE
   d  int := f_mmdd();
   d1 int := f_mmdd( +  - 1);  -- fix off-by-1 from upper bound
BEGIN
   IF d1 > d THEN
      RETURN QUERY
      SELECT *
      FROM   event e
      WHERE  f_mmdd(e.event_date) BETWEEN d AND d1
      ORDER  BY f_mmdd(e.event_date), e.event_date;

   ELSE  -- wrap around end of year
      RETURN QUERY
      SELECT *
      FROM   event e
      WHERE  f_mmdd(e.event_date) >= d OR
             f_mmdd(e.event_date) <= d1
      ORDER  BY (f_mmdd(e.event_date) >= d) DESC, f_mmdd(e.event_date), event_date;
      -- chronological across turn of the year
   END IF;
END
$func$;

SELECT * FROM f_anniversary();

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn