db2_sql

Funzione SQL DB2 per calcolo anno – settimana

db2_sqlNel 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.

(Letto 2.852 volte di cui 1 negli ultimi 30gg)
twitterlinkedinmailby feather

One thought on “Funzione SQL DB2 per calcolo anno – settimana

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *