2009-08-13 13 views

risposta

23

Se non si utilizza un MySQL antico, è possibile eseguire il wrapping in una funzione memorizzata.

CREATE FUNCTION `LastMonday`() RETURNS DATETIME  
    RETURN DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY) ; 

e quindi chiamare

select LastMonday() as LastMonday 

Aggiornamento:

In caso di problemi di prestazioni, si può persistere il valore in una variabile di sessione. In questo modo puoi essere sicuro che verrà calcolato solo una volta.

set @LastMonday=LastMonday(); 
select @Lastmonday; 

(in questo semplice query non fa alcuna differenza, naturalmente ...)

+0

questo è esattamente il modo in cui avevo "evitato" i lunghi calcoli di date fino ad ora ... Ero/sono preoccupato per il potenziale sovraccarico ... – lexu

+0

Da allora ho aggiunto il tuo suggerimento "aggiornamento prestazioni" al nostro codice base. Fa una grande differenza, in qualche modo mi aspettavo che la funzione venisse chiamata solo una volta .. (ma come fa l'ottimizzatore a sapere che non restituisco il tempo in millisecondi ..) – lexu

+0

Il trucco qui è che il valore viene calcolato una volta e quindi memorizzato manualmente. Puoi provare cosa fa l'ottimizzatore. Potrebbe essere abbastanza intelligente da metterlo nella cache, ma non puoi davvero fare affidamento su di esso. –

-1

Prova questo:

-- Today is 05 April 2013 

-- Get Last Monday from MySQL 

SELECT DATE_FORMAT(LAST_DAY(NOW()) - ((7 + WEEKDAY(LAST_DAY(NOW())) - 7) % 7), '%Y-%m-%d') last_monday; 

-- Output 

last_monday 
------------- 
2013-04-29 
+0

Per me non è né più semplice né più performante del codice nella domanda? .. ma prenderò il suggerimento e riformulerò il titolo della domanda! – lexu

+0

Per me, questo output non è il prossimo lunedì ma il lunedì successivo. – DanM7

0
SET @dateCurrent = CURDATE(); 
SET @dateCurrentDayInWeek = DAYOFWEEK(@dateCurrent) - 2; 
SET @dateLastMonday = DATE_ADD(@dateCurrent, INTERVAL [email protected] DAY); 

SELECT @dateLastMonday; 
Problemi correlati