Question : Modify SP to return degree day total for each month

I need to add the facility in the SP below, that when, the AvgOAT for each day taken and used in the formula:

Daily DegreeDays=Max(AvgOAT-15.5, 0)

For a Year report, the monthly totals of degreedays should be returned, for all other reports, days are returned anyway, so nnot so much of an issue.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
USE [EnergySuiteDB]
GO
/****** Object:  StoredProcedure [dbo].[GetCostPerPeriod]    Script Date: 08/14/2010 19:40:14 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[GetCostPerPeriod] @sDate DATETIME,@Meter int,@GasRate int,@pf float,@util varchar(50),@reportselection char(1),@co2 float,@Carbon float,@calc float, @occtl int, @oattl int, @Spacetl int

AS
BEGIN

--A power factor of 0 will throw exception, so this needs to be taken care of
if isnull(@pf,0)=0 set @pf = 1

-- declare and set up some variables based on incoming parameters

DECLARE @PrevVal NUMERIC(12, 4)
declare @grate numeric(12,4)
declare @edate datetime
declare @intervals int

set @sdate = convert(char(8),@sdate,112)   -- make sure time is at "start" of period
If @reportselection = 'M' set @sdate = DATEADD(month, DATEDIFF(month, 0, @sdate),0)
If @reportselection = 'Y' set @sdate = datename(year,@sdate) + '0101'

set @edate = convert(char(8),@sdate,112) + ' 23:59:59.997'
If @reportselection = 'W' set @edate = convert(char(8),@sdate+6,112) + ' 23:59:59.997'
If @reportselection = 'M' set @edate = DATEADD(month, DATEDIFF(month, -1, @sdate),0) - 0.00000005
If @reportselection = 'Y' set @edate = datename(year,@sdate) + '1231 23:59:59.997'

set @intervals = day(dateadd(month,datediff(month,-1,@sdate),0) - 1) 
If @reportselection = 'D' set @intervals = @intervals * 96  -- 96 quarter hours in a day.
If @reportselection = 'Y' set @intervals = 1

if isnull(@gasrate,0) = 1
   set @grate = 11.0786 -- 1.02264 * 39 / 3.6
else
   set @grate = 1.0

-- now create our temp report data extract from main history table

IF OBJECT_ID('tempdb..#ReportData','U') IS NOT NULL DROP TABLE #ReportData  -- should not be needed
 
CREATE TABLE #ReportData
(
    ID int identity primary key,
    TimeStamp DATETIME,
    Hundredths INT,      
    Data NUMERIC(12, 4),
    DataChange NUMERIC(12, 4),
    DateStamp datetime,
    Occupancy int,
    OAT numeric (12,4),
    SpaceTemp numeric (12,4)

)

-- populate our report data

INSERT INTO #ReportData (Timestamp, Hundredths, Data, Datestamp, occupancy, OAT, SpaceTemp)
SELECT Timestamp, Hundredths, convert(real,Data) * @grate*@calc , case when @reportselection = 'Y' then convert(char(6),timestamp,112)+'01' else convert(char(8),timestamp,112) end
       ,case when @occtl = 0 then 2 else (SELECT top 1 convert(int,data) 
                 FROM HistorianDB.dbo.TLData O
                 WHERE O.TLInstance = @Occtl
                 AND O.timestamp <= M.timestamp
                 AND O.Type=0 
                 AND isnumeric(O.data) = 1
                 ORDER BY O.timestamp desc) end
       ,(SELECT top 1 convert(real,data) 
         FROM HistorianDB.dbo.TLData O
         WHERE O.TLInstance = @OatTl
         AND O.timestamp between @sdate and M.timestamp
         AND O.Type=0 
         AND isnumeric(O.data) = 1
         ORDER BY O.timestamp desc)
       ,(SELECT top 1 convert(real,data) 
         FROM HistorianDB.dbo.TLData O
         WHERE O.TLInstance = @SpaceTl
         AND O.timestamp between @sdate and M.timestamp
         AND O.Type=0 
         AND isnumeric(O.data) = 1
         ORDER BY O.timestamp desc)

FROM HistorianDB.dbo.TLData M
WHERE TLInstance = @Meter 
AND timestamp between @sdate and @edate
AND Type=0 
AND isnumeric(data)=1
ORDER BY timestamp      

-- do the update our data to calculate the difference between meter readings and cost

UPDATE #reportdata
SET    DataChange = #reportdata.Data - isnull(prev.data,#reportdata.Data)
FROM   #ReportData 
left outer join #reportdata prev on #reportdata.id - 1 = prev.id

-- now check for negative numbers dues to meter reset (or tampering)

UPDATE #reportdata  SET  DataChange = 0 WHERE DataChange < 0


-- now we can run the report

;With Periods as
(
   Select case when @reportselection = 'D' then dateadd(minute,number * 15,@sdate) else case when @reportselection = 'Y' then dateadd(month,number,@sdate) else dateadd(day,number,@sdate) end end as PSDate 
   ,case when @reportselection = 'D' then dateadd(minute,number * 15 + 15,@sdate) - 0.00000005 else case when @reportselection = 'Y' then DATEADD(month, DATEDIFF(month, -1, dateadd(month,number,@sdate)),0) - 0.00000005 else convert(char(8),@sdate+number,112) + ' 23:59:59.997' end end as PEDate 
   ,case when @reportselection = 'D' then left(datename(dw,@sdate),03) +' '+ convert(char(8),@sdate,03) +right(convert(char(19),dateadd(minute,number * 15,@sdate),100),8) else case when @reportselection = 'Y' then left(datename(month,dateadd(month,number,@sdate)),3) + ' ' + datename(year,@sdate) else left(datename(dw,dateadd(day,number,@sdate)),3) + ' ' + convert(char(8),dateadd(day,number,@sdate),03) end end as PSName 
   ,case when @reportselection = 'D' then 1.0 / 96.0 else case when @reportselection in ('M','W') then 1.0 else day(dateadd(month, number+datediff(month, -1, @sdate),0) - 1) end end as dayparts
   from master..spt_values n with (nolock) 
   where type = 'p'
   and case when @reportselection = 'D' then dateadd(minute,number * 15,@sdate) else case when @reportselection = 'Y' then dateadd(month,number,@sdate) else dateadd(day,number,@sdate) end end < @edate
)
SELECT 
    PSname as Date,
    SUM(isnull(r1.datachange,0)) AS day_data,
    SUM(isnull(r1.datachange,0))*@CO2 AS CO2_data,
    SUM(isnull(r1.datachange,0))*@Carbon AS Carbon_data,
    SUM(isnull(r1.datachange,0)*chargerate) AS DataCost,
    SUM(isnull(r1.datachange,0)*levy) as TotalLevy,
    max(case when r1.datestamp is null then 0 else caprate end)/@intervals  as TotalCap,                           
    max(case when r1.datestamp is null then 0 else chargecap end)  as ChargeCap,
    max(case when r1.datestamp is null then 0 else dayparts * StandingDayCharge end) as StandingDayCharge,
    max(case when r1.datestamp is null then 0 else dayparts * StandingDayCharge end) 
    + SUM(isnull(r1.datachange,0)*(chargerate + levy)) 
    + max(case when r1.datestamp is null then 0 else caprate end)/@intervals  as TotalCost,
    isnull(((case when @reportselection = 'D' then SUM(isnull(r1.datachange,0)) else (select top 1 datachange from #reportdata r2 where r2.datestamp = r1.datestamp order by r2.datachange desc) end)*4)/@pf,0) as MaxkVA,
    isnull(((case when @reportselection = 'D' then SUM(isnull(r1.datachange,0)) else (select top 1 datachange from #reportdata r2 where r2.datestamp = r1.datestamp order by r2.datachange desc) end)*4),0) as MaxkW,
    (select top 1 timestamp from #reportdata r2 where r2.datestamp = r1.datestamp order by r2.datachange desc,r2.timestamp desc) as MaxDataChangeTimeStamp,
    sum(case when isnull(occupancy,2) = 0 then isnull(r1.datachange,0) else 0 end) as OffHoursTotal,
    sum(case when isnull(occupancy,2) = 1 then isnull(r1.datachange,0) else 0 end) as OnHoursTotal,
    avg(isnull(r1.Spacetemp,000.0)) as AvgSpaceTemp,
    case when @reportselection = 'D' or min(isnull(r1.Spacetemp,999.9)) = 999.9 then 0.0 else min(isnull(r1.Spacetemp,999.9)) end as MinSpaceTemp,
    case when @reportselection = 'D' then 0.0 else max(isnull(r1.Spacetemp,000.0)) end as MaxSpaceTemp,
    avg(isnull(r1.oat,000.0)) as AvgOat,
    case when @reportselection = 'D' or min(isnull(r1.Oat,999.9)) = 999.9 then 0.0 else min(isnull(r1.Oat,999.9)) end as MinOat,
    case when @reportselection = 'D' then 0.0 else max(isnull(r1.oat,000.0)) end as MaxOat
 
FROM Periods
LEFT OUTER JOIN #ReportData r1 on r1.timestamp between psdate and pedate
cross apply dbo.udf_getrates_3(r1.Timestamp,@util)    
GROUP BY PSname,r1.datestamp,PSdate
ORDER BY PSdate
END

Answer : Modify SP to return degree day total for each month

Well, that was going to be the new report option in your other question - to get by quarter hour any dates between start and end and that way you can graph them / matrix them any way you want...

For degree days, we are already get avgoat, and unsure what the MAX of that would be as you have written above (other than choosing the maximum value of either the calc, or zero)...

So, was adding in :

,  case when avg(isnull(r1.oat,000.0)) > 15.5 then avg(isnull(r1.oat,000.0))-15.5 else 0.0 end as DailyDegrees

Then realised for the quarter hour report, it is still "daily" degrees not qurter hour degrees, and so can do the same lookup for a day as we need for the year report :


, (select sum(dd)
   from (select case when avg(isnull(r2.oat,000.0)) > 15.5
                     then avg(isnull(r2.oat,000.0))-15.5
                     else 0.0 end as DD
         from #reportdata r2
         where convert(char(8),r2.timestamp,112) between convert(char(8),psdate,112) and convert(char(8),pedate,112)
         group by convert(char(8),r2.timestamp,112)) dr2) as dailydegrees


which is added as a new column down the bottom before the :

...
FROM Periods
LEFT OUTER JOIN #ReportData r1 on r1.timestamp between psdate and pedate
...


And we can discuss the date range business in that other thread if OK with you ?




Random Solutions  
 
programming4us programming4us