46 messaggi dal 30 gennaio 2010
blogs.dotnethell.it
Ciao a tutti,
ho due semplici tabelle, con la stessa struttura, così fatte:

Create Table Report(Mese int, Valore float)
go
Create Table ReportCorretto(Mese int, Valore float)

ognuna con 12 righe, una per mese, e dei valori numerici:

Insert Report values(1,16),(2,11),(3,12),(4,15),(5,0),(6,34),(7,56),(8,14),(9,24),(10,0),(11,12),(12,14)
Go
Insert ReportCorretto values(1,16),(2,11),(3,12),(4,15),(5,11),(6,34),(7,56),(8,14),(9,24),(10,31),(11,12),(12,14)

Come si vede, nella tabella Report, per i mesi di maggio e ottobre ho zero come Valore.
A questo punto devo andare sulla tabella ReportCorretto, prendere i valori per questi due mesi (11 e 31), e inserirli in una terza tabella con la stessa struttura (Mese, Valore) ed inserire tali valori con il mese successivo a quello che ho trovato con lo zero.

Dovrei quindi avere:

Mese - Valore
6 - 11
11 - 31

Il problema però è che se trovo due mesi vicini che hanno zero entrambi, devo sommare i rispettivi valori e posizionarli al primo mese che ha un valore.

Ad esempio, se avesso avuto anche giugno con valore=0, avrei dovuto sommare 11+34 (=45) e metterlo a luglio, ottenendo:

7-45
11-31

Come posso risolvere questo intricato meccanismo?
(Posso usare solo SQL Server 2000).

Grazie
Luigi
1.940 messaggi dal 27 luglio 2005
Contributi
salve Luigi,
GigiMI wrote:
Ciao a tutti,
ho due semplici tabelle, con la stessa struttura, così fatte: Create Table Report(Mese int, Valore float)
go
Create Table ReportCorretto(Mese int, Valore float)
ognuna con 12 righe, una per mese, e dei valori numerici:
Insert Report
values(1,16),(2,11),(3,12),(4,15),(5,0),(6,34),(7,56),(8,14),(9,24),(10,0),( 11,12),(12,14)
Go
Insert ReportCorretto
values(1,16),(2,11),(3,12),(4,15),(5,11),(6,34),(7,56),(8,14),(9,24),(10,31) ,(11,12),(12,14)
Come si vede, nella tabella Report, per i mesi di maggio e ottobre ho zero come Valore.
A questo punto devo andare sulla tabella ReportCorretto, prendere i valori per questi due mesi (11 e 31), e inserirli in una terza tabella con la stessa struttura (Mese, Valore) ed inserire tali valori con il mese successivo a quello che ho trovato con lo zero. Dovrei quindi avere:
Mese - Valore
6 - 11
11 - 31
Il problema però è che se trovo due mesi vicini che hanno zero entrambi, devo sommare i rispettivi valori e posizionarli al primo mese che ha un valore.
Ad esempio, se avesso avuto anche giugno con valore=0, avrei dovuto sommare 11+34 (=45) e metterlo a luglio, ottenendo:
7-45
11-31
Come posso risolvere questo intricato meccanismo?
(Posso usare solo SQL Server 2000).
Grazie
Luigi

ehh... SQL Server 2000.... mi mancano tanto le common table expressions  vabbeh.. si puo' eventualmente ovviare con delle tabelle temporanee... prova a vedere se il seguente esempio triviale ti pone sulla giusta via
SET NOCOUNT ON;
USE tempdb;
GO
Create Table Report(Mese int, Valore float)
go
Create Table ReportCorretto(Mese int, Valore float)
Insert Report
values(1,16),(2,11),(3,12),(4,15),(5,0),(6,34),(7,56),(8,14),(9,24),(10,0),( 11,12),(12,14)
Go
Insert ReportCorretto
values(1,16),(2,11),(3,12),(4,15),(5,11),(6,34),(7,56),(8,14),(9,24),(10,31) ,(11,12),(12,14)
GO
PRINT 'report completo';
SELECT r.Mese,
CASE WHEN r.Valore = 0 THEN rc.Valore ELSE r.Valore END AS [ValoreInterpolato]
FROM Report r
JOIN ReportCorretto rc
ON rc.Mese = r.Mese;

PRINT 'righe interpolate da inserire nella situazione semplice'; PRINT 'di assenza di valori a 0 consecutivi';
SELECT r.Mese + 1 AS [Mese da aggiornare],
CASE WHEN r.Valore = 0 THEN rc.Valore ELSE r.Valore END AS [ValoreInterpolato]
FROM Report r
JOIN ReportCorretto rc
ON rc.Mese = r.Mese
WHERE r.Valore = 0;
GO
PRINT 'giugno a 0';
UPDATE Report
SET Valore = 0
WHERE Mese = 6;
GO
CREATE FUNCTION dbo.ufn_Report$TrovaProssimoMese (
@MinMese int
)
RETURNS int
AS BEGIN
RETURN
(
SELECT MIN(r.Mese)
FROM Report r
WHERE r.Mese > @MinMese
AND r.Valore <> 0
);
END;
GO
SELECT r.Mese,
r.Valore,
CASE WHEN r.Valore = 0 THEN rc.Valore ELSE r.Valore END AS [ValoreInterpolato]
FROM Report r
JOIN ReportCorretto rc
ON rc.Mese = r.Mese;

GO
CREATE TABLE #t (
MeseIn int,
MeseOut int
);

INSERT INTO #t
SELECT r.Mese AS [MeseIn], dbo.ufn_Report$TrovaProssimoMese (r.Mese) AS [MeseOut]
FROM Report r
WHERE r.Valore = 0;

PRINT 'interpolazione dei mesi';
SELECT *
FROM #t;

PRINT 'raggruppamento per mese ''buco'' con ottenimento';
PRINT 'dell''interpolazione in presenza di 0 consecutivi';
CREATE TABLE #t2 (
MeseIn int,
MeseOut int
);

PRINT '--
ma cosa si fa con MeseOut = NULL????'
INSERT INTO #t2
SELECT MIN(t.MeseIn), t.MeseOut
FROM #t t
GROUP BY t.MeseOut;

PRINT 'interpolazione finale dei mesi';
SELECT *
FROM #t2;

SELECT r.Mese AS [Mese Report]
, rc.Mese AS [Mese ReportCorretto]
, t.MeseOut AS [Mese da aggiornare]
, (
SELECT SUM(Valore)
FROM ReportCorretto rc2
WHERE rc2.Mese >= r.Mese
AND rc2.Mese < t.MeseOut
) AS [Valore da Usare]
FROM Report r
JOIN #t2 t ON r.Mese = t.MeseIn
JOIN ReportCorretto rc ON rc.Mese = t.MeseOut
WHERE r.Valore = 0;

DROP TABLE #t;
DROP TABLE #t2;
GO
PRINT 'ripristino condizione iniziale';
TRUNCATE TABLE ReportCorretto;
TRUNCATE TABLE Report;
GO
Insert Report
values(1,16),(2,11),(3,12),(4,15),(5,0),(6,34),(7,56),(8,14),(9,24),(10,0),( 11,12),(12,14)
Go
Insert ReportCorretto
values(1,16),(2,11),(3,12),(4,15),(5,11),(6,34),(7,56),(8,14),(9,24),(10,31) ,(11,12),(12,14)
GO
PRINT 'verifica';
CREATE TABLE #t (
MeseIn int,
MeseOut int
);

INSERT INTO #t
SELECT r.Mese AS [MeseIn], dbo.ufn_Report$TrovaProssimoMese (r.Mese) AS [MeseOut]
FROM Report r
WHERE r.Valore = 0;

CREATE TABLE #t2 (
MeseIn int,
MeseOut int
);

INSERT INTO #t2
SELECT MIN(t.MeseIn), t.MeseOut
FROM #t t
GROUP BY t.MeseOut;

SELECT r.Mese AS [Mese Report]
, rc.Mese AS [Mese ReportCorretto]
, t.MeseOut AS [Mese da aggiornare]
, (
SELECT SUM(Valore)
FROM ReportCorretto rc2
WHERE rc2.Mese >= r.Mese
AND rc2.Mese < t.MeseOut
) AS [Valore da Usare]
FROM Report r
JOIN #t2 t ON r.Mese = t.MeseIn
JOIN ReportCorretto rc ON rc.Mese = t.MeseOut
WHERE r.Valore = 0;

DROP TABLE #t;
DROP TABLE #t2;

GO
DROP FUNCTION dbo.ufn_Report$TrovaProssimoMese;
DROP TABLE ReportCorretto, Report;
GO
--<---------
report completo
Mese ValoreInterpolato
---------
----------------------
1 16
2 11
3 12
4 15
5 11
6 34
7 56
8 14
9 24
10 31
11 12
12 14

righe interpolate da inserire nella situazione semplice
di assenza di valori a 0 consecutivi
Mese da aggiornare ValoreInterpolato
----------------
----------------------
6 11
11 31

giugno a 0
Mese Valore ValoreInterpolato
---------
--------------------
----------------------
1 16 16
2 11 11
3 12 12
4 15 15
5 0 11
6 0 34
7 56 56
8 14 14
9 24 24
10 0 31
11 12 12
12 14 14

interpolazione dei mesi
MeseIn MeseOut
---------
-----------
5 7
6 7
10 11

raggruppamento per mese 'buco' con ottenimento
dell'interpolazione in presenza di 0 consecutivi
interpolazione finale dei mesi
MeseIn MeseOut
---------
-----------
5 7
10 11

--
ma cosa si fa con MeseOut = NULL????

Mese Report Mese ReportCorretto Mese da aggiornare Valore da Usare ---------
-----------------
----------------
--------------------
5 7 7 45
10 11 11 31

ripristino condizione iniziale
verifica
Mese Report Mese ReportCorretto Mese da aggiornare Valore da Usare ---------
-----------------
----------------
--------------------
5 6 6 11
10 11 11 31


ti avverto che, anche per mancanza di una tua corretta definizione "dell'anno" in quanto tale, non ci sara' un risultato nei casi di vuoti temporali, dove cioe' i risultati siano un empty set e quindi "MeseOut" sia NULL dovuti al fatto che non esistono mesi successivi che abbiano valori diversi da 0.. non avresti infatti in questo caso il "prossimo mese" da utilizzare..
saluti

Andrea Montanari
http://www.hotelsole.com - http://www.hotelsole.com/asql/index.php

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.