Viste su SQL2000/2005

giovedì 06 novembre 2008 - 14.02

fotw Profilo | Newbie

Saluti a tutti, ho bisogno di un aiuto

Devo creare una vista che generi una riga per ogni mese.

Esempio:
CREATE TABLE dbo.dati(id int, datainzio datetime, datafine datetime, nummesi int, impmensile float)
GO

INSERT INTO dbo.dati VALUES (1, '01/01/2008', '12/31/2008', 12, 2400)
INSERT INTO dbo.dati VALUES (2, '01/01/2008', '02/29/2008', 2, 200)
INSERT INTO dbo.dati VALUES (3, '01/03/2008', '04/30/2008', 2, 200)
INSERT INTO dbo.dati VALUES (4, '01/05/2008', '06/30/2008', 2, 200)
INSERT INTO dbo.dati VALUES (5, '01/01/2008', '06/30/2008', 6, 1200)
INSERT INTO dbo.dati VALUES (6, '01/01/2009', '06/30/2009', 6, 1500)

DROP TABLE dbo.dati
GO


Dovrei ottenere una vista con i seguenti records
data inizio Data fine N.ro mese Importo mese
01/01/2008 01/31/2008 1 2400
02/01/2008 02/29/2008 2 2400
03/01/2008 03/31/2008 3 2400
04/01/2008 04/30/2008 4 2400
....
11/01/2008 11/30/2008 11 2400
12/01/2008 12/31/2008 12 2400
01/01/2008 01/31/2008 1 200
02/01/2008 02/29/2008 2 200
03/01/2008 03/31/2008 3 200
04/01/2008 04/30/2008 4 200
05/01/2008 05/31/2008 5 200
06/01/2008 06/30/2008 6 200
01/01/2008 01/31/2008 1 1200
02/01/2008 02/29/2008 2 1200
03/01/2008 03/31/2008 3 1200
04/01/2008 04/30/2008 4 1200
05/01/2008 05/31/2008 5 1200
06/01/2008 06/30/2008 6 1200
01/01/2009 01/31/2009 1 1500
02/01/2009 02/28/2009 2 1500
03/01/2009 03/31/2009 3 1500
04/01/2009 04/30/2009 4 1500
05/01/2009 05/31/2009 5 1500
06/01/2009 06/30/2009 6 1500

Praticamente per ogni riga della tabella avere tante righe per quanti sono i mesi (nummesi), il numero dei mesi può
assumere i valori più disparati

Grazie 1000

lbenaglia Profilo | Guru

>Praticamente per ogni riga della tabella avere tante righe per
>quanti sono i mesi (nummesi), il numero dei mesi può
>assumere i valori più disparati

Non ho capito il significato della colonna nummesi dato che in base al risultato che hai postato è logicamente correlata con datainzio e datafine, quindi ricavabile da una banale differenza in mesi tra le due date.
Di conseguenza NON "può assumere i valori più disparati", altrimenti il tutto perderebbe di significato.
Facciamo un esempio.

INSERT INTO dbo.dati VALUES (1, '01/01/2008', '12/31/2008', 12, 2400)

Come prima cosa per le date utilizza SEMPRE il formato ANSI SQL 'YYYYMMDD'.
In secondo luogo che senso avrebbe un valore di nummesi differente da 12?
Mi sfugge qualcosa?

>Grazie 1000
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

fotw Profilo | Newbie

Hai ragione quando sostieni che numero di mesi si può ricavare per differenza dalle date, l'ho inserita solo per semplicità.
Il numero mesi, invece, può assumere qualsiasi valore in quanto posso avere anche data inizio e fine a cavallo di più anni solari
(Es. dal 01/01/2007' al 31/08/2008 sono 20 mesi).

Grazie e ciao

lbenaglia Profilo | Guru

>Hai ragione quando sostieni che numero di mesi si può ricavare
>per differenza dalle date, l'ho inserita solo per semplicità.
Tutto ciò che è ridondante finisce per creare problemi.
Quei mesi non servono, quindi eliminali dalla struttura della tabella.
Inoltre mi pare di capire che l'ultima colonna sia un importo.
NON UTILIZZARE MAI dei data type approssimati come real e float per memorizzare degli importi se non vuoi introdurre degli errori di approssimazione.
Dato che nell'esempio hai inserito numeri interi, ho sostituito il data type in int.

USE tempdb; CREATE TABLE dbo.dati( id int NOT NULL PRIMARY KEY, datainizio datetime NOT NULL, datafine datetime NOT NULL, impmensile int NOT NULL ); INSERT dbo.dati VALUES (1, '20080101', '20081231', 2400); INSERT dbo.dati VALUES (2, '20080101', '20080219', 200); INSERT dbo.dati VALUES (3, '20080301', '20080430', 200); INSERT dbo.dati VALUES (4, '20080501', '20080630', 200); INSERT dbo.dati VALUES (5, '20080101', '20080630', 1200); INSERT dbo.dati VALUES (6, '20090101', '20090630', 1500); GO CREATE FUNCTION dbo.ufn_GetData( @From datetime, @To datetime ) RETURNS @Data TABLE( datainizio datetime NOT NULL, datafine datetime NOT NULL ) BEGIN WHILE @From < DATEADD(month, -1, @To) BEGIN INSERT @Data VALUES(@From, DATEADD(month, 1, @From) - 1); SET @From = DATEADD(month, 1, @From); END INSERT @Data VALUES(@From, @To); RETURN END GO SELECT F.* , D.impmensile FROM dbo.dati AS D CROSS APPLY dbo.ufn_GetData(D.datainizio, D.datafine) AS F; /* Output: datainizio datafine impmensile ----------------------- ----------------------- ----------- 2008-01-01 00:00:00.000 2008-01-31 00:00:00.000 2400 2008-02-01 00:00:00.000 2008-02-29 00:00:00.000 2400 2008-03-01 00:00:00.000 2008-03-31 00:00:00.000 2400 2008-04-01 00:00:00.000 2008-04-30 00:00:00.000 2400 2008-05-01 00:00:00.000 2008-05-31 00:00:00.000 2400 2008-06-01 00:00:00.000 2008-06-30 00:00:00.000 2400 2008-07-01 00:00:00.000 2008-07-31 00:00:00.000 2400 2008-08-01 00:00:00.000 2008-08-31 00:00:00.000 2400 2008-09-01 00:00:00.000 2008-09-30 00:00:00.000 2400 2008-10-01 00:00:00.000 2008-10-31 00:00:00.000 2400 2008-11-01 00:00:00.000 2008-11-30 00:00:00.000 2400 2008-12-01 00:00:00.000 2008-12-31 00:00:00.000 2400 2008-01-01 00:00:00.000 2008-01-31 00:00:00.000 200 2008-02-01 00:00:00.000 2008-02-19 00:00:00.000 200 2008-03-01 00:00:00.000 2008-03-31 00:00:00.000 200 2008-04-01 00:00:00.000 2008-04-30 00:00:00.000 200 2008-05-01 00:00:00.000 2008-05-31 00:00:00.000 200 2008-06-01 00:00:00.000 2008-06-30 00:00:00.000 200 2008-01-01 00:00:00.000 2008-01-31 00:00:00.000 1200 2008-02-01 00:00:00.000 2008-02-29 00:00:00.000 1200 2008-03-01 00:00:00.000 2008-03-31 00:00:00.000 1200 2008-04-01 00:00:00.000 2008-04-30 00:00:00.000 1200 2008-05-01 00:00:00.000 2008-05-31 00:00:00.000 1200 2008-06-01 00:00:00.000 2008-06-30 00:00:00.000 1200 2009-01-01 00:00:00.000 2009-01-31 00:00:00.000 1500 2009-02-01 00:00:00.000 2009-02-28 00:00:00.000 1500 2009-03-01 00:00:00.000 2009-03-31 00:00:00.000 1500 2009-04-01 00:00:00.000 2009-04-30 00:00:00.000 1500 2009-05-01 00:00:00.000 2009-05-31 00:00:00.000 1500 2009-06-01 00:00:00.000 2009-06-30 00:00:00.000 1500 (30 row(s) affected) */ DROP FUNCTION dbo.ufn_GetData; DROP TABLE dbo.dati;

Come vedi la logica è contenuta nella Multistatement Table-valued Function dbo.ufn_GetData la quale per ogni coppia di date provvede a generare un set di righe. L'operatore CROSS APPLY permette di invocare la funzione per ogni riga restituita dalla tabella dbo.dati.

>Grazie e ciao
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2023
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5