Problem:
Sie möchten Datumsangaben auswählen, die Folgendes haben ein Jubiläum innerhalb der nächsten 14 Tage, aber Sie möchten dies erreichen, indem Sie das Jahr ausschließen.
Beispiel Abfrage:
SELECT * FROM events WHERE EXTRACT(month FROM "date") = 3 AND EXTRACT(day FROM "date") < EXTRACT(day FROM "date") + 14;
Herausforderung:
Die obige Abfrage funktioniert nicht, da sie den Wrap-Around-Effekt von Monaten nicht berücksichtigt.
Lösungen:
1. Erweiterte Version
Diese Lösung verwendet eine benutzerdefinierte SQL-Funktion und einen mehrspaltigen Index für optimale Leistung.
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. Tabellenfunktion
Diese Lösung verwendet eine PostgreSQL-Tabellenfunktion, um die Jubiläumsberechnung durchzuführen.
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();
Das obige ist der detaillierte Inhalt vonWie berechnet man Datumsangaben ohne Berücksichtigung des Jahres in SQL?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!