Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
alanhuro
Starting Member
34 Posts |
Posted - 2008-12-30 : 14:17:13
|
| Hello Guys/Gals, Merry Christmas and Happy new year.It is sucked that getting close to new year but I'm still in my cubical debugging SQL code.I try to write a daily report and could not figure out how to fill in the days that are missing from database. For instance I havedate___________Test Result2008-12-01________122008-12-03________192008-12-03________182008-12-03________172008-12-07________302008-12-07________32...I want to generate a report which include all the days for a month. For a day which does not have data the result will be null. here is an exampleDate___________Test Result2008-12-01________122008-12-02________Null2008-12-03________avg(19, 18, 17)2008-12-04________Null2008-12-05________Null2008-12-06________Null2008-12-07________avg(30, 32)ThanksAlan |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-12-30 : 14:27:39
|
| [code]DECLARE @Dates TABLE(ID int identity(1,1),dateval datetime)DECLARE @MaxDate datetime,@minDate datetime,@Days intSELECT @MaxDate=MAX(date),@MinDate=MIN(date)FROM YourTableSET @Days =DATEDIFF(dd,@MinDate,@MaxDate)+1WHILE @Days>=0BEGININSERT INTO @Dates(dateval)SELECT DATEADD(dd,-1*@Days,@MaxDate)SET @Days=@Days-1ENDSELECT d.dateval,t.TestResultFROM @Dates dLEFT JOIN (SELECT date,AVG(TestResult*1.0) AS TestResult FROM YourTable GROUP BY date)tON t.date=d.dateval[/code] |
 |
|
|
Nageswar9
Aged Yak Warrior
600 Posts |
Posted - 2008-12-30 : 23:50:45
|
| Try this declare @temp1 table ( date1 datetime,testresult1 int)declare @i int,@date varchar(32) set @i = 1while (@i<=30)beginselect @date = date from @tempselect @date = DATEADD(D,0,DATEADD(D,-DAY(@date)+cast(@i as varchar(10)),@date))select @i = @i +1insert into @temp1select @date,avg(testresult) from @temp where datediff(d,@date,date) = 0endselect * from @temp1 |
 |
|
|
raky
Aged Yak Warrior
767 Posts |
Posted - 2008-12-31 : 00:11:34
|
quote: Originally posted by visakh16
DECLARE @Dates TABLE(ID int identity(1,1),dateval datetime)DECLARE @MaxDate datetime,@minDate datetime,@Days intSELECT @MaxDate=MAX(date),@MinDate=MIN(date)FROM YourTableSET @Days =DATEDIFF(dd,@MinDate,@MaxDate)+1WHILE @Days>=0BEGININSERT INTO @Dates(dateval)SELECT DATEADD(dd,-1*@Days,@MaxDate)SET @Days=@Days-1ENDSELECT d.dateval,t.TestResultFROM @Dates dLEFT JOIN (SELECT date,AVG(TestResult*1.0) AS TestResult FROM YourTable GROUP BY date)tON t.date=d.dateval
Slight modification to visakh's solutin to give the expected resultchange SET @Days =DATEDIFF(dd,@MinDate,@MaxDate)+1 to SET @Days =DATEDIFF(dd,@MinDate,@MaxDate) |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-12-31 : 04:05:20
|
[code]-- Prepare dummy or sample data hereDECLARE @Sample TABLE ( dt DATETIME, rslt INT )INSERT @SampleSELECT '2008-12-01', 12 UNION ALLSELECT '2008-12-03', 19 UNION ALLSELECT '2008-12-03', 18 UNION ALLSELECT '2008-12-03', 17 UNION ALLSELECT '2008-12-07', 30 UNION ALLSELECT '2008-12-07', 32-- The solution starts here;WITH Yak (theDate, maxDate)AS ( SELECT MIN(dt), MAX(dt) FROM @Sample UNION ALL SELECT theDate + 1, maxDate FROM Yak WHERE theDate < maxDate)-- Display the final resultsetSELECT dt AS theDate, AVG(1.0E * rslt) AS theAverageFROM ( SELECT dt, rslt FROM @Sample UNION ALL SELECT theDate, NULL FROM Yak ) AS dGROUP BY dtORDER BY dt[/code] E 12°55'05.63"N 56°04'39.26" |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2008-12-31 : 04:12:53
|
I choose to use UNION ALL in favor of LEFT JOIN because of performance.A NULL values doesn't add to the average anyway. E 12°55'05.63"N 56°04'39.26" |
 |
|
|
|
|
|
|
|