Funzione SQL DB2 per calcolo anno – settimana
Nel DB2 SQL for i (AS/400) esistono funzioni che permettono di calcolare il numero della settimana di una certa data e sono WEEK e WEEK_ISO.
La principali differenze tra loro sono che WEEK considera che la settimana inizia con Domenica e l'1 Gennaio è sempre parte della PRIMA SETTIMANA dell'anno, mentre WEEK_ISO considera che la settimana inizia con Lunedì e la PRIMA SETTIMANA dell'anno è sempre la prima che contiene Giovedì, quindi ad esempio, se Il primo Giovedì dell'anno capita il 6 gennaio significa che la prima settimana è quella che inizia con lunedì 3 gennaio mentre Domenica 1 e Sabato 2 fanno parte dell'ultima settimana dell'anno precedente.
Entrambe queste funzioni chiedono in input una data nel formato DATE; purtroppo molte tabelle su IBMi (AS/400) hanno le date registrare in colonne dichiarate come DECIMAL (8, 0), esempio: 20130310.
Quindi per utilizzare le funzioni sopraindicate bisogna convertire le data numerica nel formato DATE utilizzando le sottostringhe.
Inoltre, queste funzioni restituiscono “solo” il numero della settimana e non l'anno di competenza e questo può essere fuorviante.
Ad esempio: se si usa la funzione WEEK_ISO con la data 31 Dicembre 2013 si ottiene 1 che però è la settimana 1 del 2014, oppure se la si usa con con la data 1 Gennaio del 2012 (Domenica) si ottiene 52 che però è la 52esima settimana dell'anno precedente 2011.
Per questi motivi ho creato la seguente funzione SQL
/* --------------------------------------------------------------------------- Questa funzione restituisce la settimana di una data ricevuta in input nel classico formato numerico (8,0 - YYYYMMDD). week400 ( , ) INPUT: - data (8,0) nel formato YYYYMMDD - formato settimana (6) - YYYYWW - WW OUTPUT: - settimana (6): YYYYWW o WW ------------------------------------------------------------------------------*/ DROP FUNCTION WEEK400; CREATE FUNCTION WEEK400 ( DataInp DEC(8, 0), WeekFmt varchar(6) ) RETURNS CHAR(6) LANGUAGE SQL BEGIN declare WeekOut char(6) DEFAULT ' '; declare Anno dec(4, 0) DEFAULT 0; declare Settimana dec(2, 0) DEFAULT 0; If DataInp = 0 then WeekOut = ' '; ELSE set Settimana = week_iso( substr(char(DataInp), 1, 4) concat '-' concat substr(char(DataInp), 5, 2) concat '-' concat substr(char(DataInp), 7, 2) ); IF WeekFmt = 'WW' THEN set WeekOut = digits(Settimana); ELSE set Anno = int(DataInp) / 10000; /* ...se il mese è Dicembre e la Settimana è uno significa che è la prima settimana dell'anno successivo, quindi lo incremento */ IF substr(char(DataInp), 5, 2)='12' and Settimana = 1 THEN set Anno = Anno + 1; END IF; /* ...se il mese è Gennaio e la Settimana è superiore a 50 significa che è l'ultima settimana dell'anno precedente, quindi lo decremento */ IF substr(char(DataInp), 5, 2)='01' and Settimana > 50 THEN set Anno = Anno - 1; END IF; set WeekOut = trim(char(Anno)) concat digits(Settimana); END IF; END IF; return WeekOut; end;
Questa funzione, chiamata con molta fantasia week400, riceve in input i seguenti valori:
- data di cui si vuole calcolare il numero settimana nel formato numerico (8, 0)
- formato desiderato della settimana calcolata, ovvero:
- YYYYWW: significa che la settimana che si ottiene sarà nel formato AnnoSettimana, esempio 201325 o 201401
- WW: significa che la settimana sarà senza l'anno, esempio 25 o 01
In output fornisce ovviamente la settimana nel formato richiesto in input.
L'utilizzo è semplicissimo.
Esempio utilizzo in SQL:
select ..., week400(MiaData, 'YYYYWW'), ... from
Esempio utilizzo in programma RPG:
... D MiaSettimana s 6 ... /free ... Exec Sql set :MiaSettimana = Week400(:MiaData, 'YYYYWW'); oppure Exec Sql set :MiaSettimana = Week400(:MiaData, 'WW'); ... /end-free
Nella funzione uso la funzione WEEK_ISO perchè trovo che sia quella più adatta agli standard che si usano abitualmente, ma se qualcuno preferisse il criterio della funzione WEEK è sufficiente sostituirla all'interno del sorgente.
One thought on “Funzione SQL DB2 per calcolo anno – settimana”