Generare un recordset contenente tutti gli elementi di un intervallo in SQL Server 2005 13 Aprile 2008
Posted by gianfrasoft in Transact SQL.Tags: Common Table Expression, CTE, date, elementi, Generare un recordset contenente, interval, intervallo, SQL Server 2005
trackback
Talvolta ci si trova a dover incrociare i dati di una query con le date di uno specifico intervallo.
Ad esempio, consideriamo una tabella che contiene le vendite effettuate da un’azienda nell’arco di un anno: vogliamo rappresentare in un recordset gli importi totali delle vendite di ogni mese. La questione si risolve con un semplice raggruppamento dati, ammenocché non si voglia riportare un importo nullo anche in corrispondenza dei mesi in cui non sono state effettuate vendite.
La soluzione ideale è quella di effettuare il raggruppamento dopo avere incrociato i dati delle vendite con un recordset contenente una riga per ciascuna data di inizio o di fine mese. Questo è possibile generando una tabella temporanea e popolandola, prima di effettuare la query sulle vendite.
Un’alternativa che agisca on the fly è quella basata sulle CTE ovvero Common Table Expression: le CTE consentono di effettuare query SQL di tipo ricorsivo, che è proprio quanto a noi serve.
Nell’esempio seguente, ho realizzato uno script SQL che produce un recordset contenente tutte le date di tipo inizio mese che coprono il periodo che va dall’01/01/2007 all’01/01/2008:
WITH CTE(X) AS ( SELECT X = convert(datetime, '20070101') UNION ALL SELECT X = DATEADD(month, 1, X) FROM CTE WHERE X < '20080101' ) SELECT X FROM CTE ORDER BY X
Il recordset X può facilmente essere messo in join nell’ambito dello script “SELECT X…”.
Da questo script è facile ricavare recordset contenenti, ad esempio, intervalli di numerazione progressiva ascendene o discendente.
Attenzione, però: testando questa query su intervalli di date che richiedono più di 100 ricorsioni ci s’imbatterà nel messaggio di errore: “Istruzione interrotta. Numero massimo di ricorsioni 100 esaurito prima del completamento dell’istruzione.”. Difatti, il numero massimo di ricorsioni possibili di default in SQL Server è limitato a 100. Per consentire alla query di superare questo limite basterà fissare un nuovo limite e dichiararlo nell’ambito della stessa interrogazione con l’opzione MAXRECURSION come di seguito riportato:
WITH CTE(X) AS ( SELECT X = convert(datetime, '20070101') UNION ALL SELECT X = DATEADD(month, 1, X) FROM CTE WHERE X < '20200101' ) SELECT X FROM CTE ORDER BY X OPTION (MAXRECURSION 500);
Nell’esempio appena descritto l’intervallo di date restituisce un recordset di 157 elementi e senza l’opzione di cui all’ultima riga andrebbe in errore.
Commenti»
No comments yet — be the first.