Question : Modify SP to get totals cross referenced against on/off hours

I'm using the SP and function below to return totals from a datalogger device, which is logging accumulative values every 15mins.

Somehow I need to add into this SP, the ability to pass an extra param called '@OccTL', and cross reference datachange against the data from the HistorianDB.DBO.TLData where TLInstance = @OccTL.

The data from @OccTL will be either 1 or 0. If the timestamp needs to be checked against the OccTL data, when the Value for the current timestamp is 0, the datachange is totaled to a OffHoursTotal, when the OccTL data is 1, the datachange is totalled to OnHoursTotal. The overall daya_data, should still be returned as it currently is. So we are just adding 2 extra columns for OffHoursTotal and OnHoursTotal.

I think if @OccTL is passed as 0, the OffHourTotal and OnHourTotal are ignored, incase no historical data was recorded.
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:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
USE [EnergySuiteDB]
GO
/****** Object:  StoredProcedure [dbo].[GetCostPerPeriod]    Script Date: 07/31/2010 06:18:55 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[GetCostPerPeriod] @sDate DATETIME,@Meter varchar(50),@GasRate int,@pf float,@util varchar(50),@reportselection char(1),@co2 float,@Carbon float,@calc float

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
)

-- populate our report data

INSERT INTO #ReportData (Timestamp, Hundredths, Data, Datestamp)
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
FROM HistorianDB.dbo.TLData 
WHERE TLInstance = @Meter 
AND timestamp between @sdate and @edate
AND Type=0 
AND isnumeric(data)=1
ORDER BY timestamp, recordnumber        

-- now prepare to update our data to calculate the difference between meter readings, but we need a starting point...

SET @PrevVal = isnull( (SELECT top 1 convert(real,Data) * @grate
                        FROM HistorianDB.dbo.TLData 
                        WHERE TLInstance = @Meter 
                        AND timestamp < @sdate
                        AND Type=0 
                        AND isnumeric(data)=1 
                        ORDER BY timestamp desc) , 0)

-- 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
 
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


----------------------------------------------

USE [EnergySuiteDB]
GO
/****** Object:  UserDefinedFunction [dbo].[udf_getrates_3]    Script Date: 07/31/2010 06:19:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[udf_getrates_3] (@date datetime,@util varchar(50))
RETURNS @tbl table (chargerate MONEY, levy MONEY, caprate MONEY,ChargeCap float, StandingDayCharge money)
AS
BEGIN


  declare @dw char(1)
  set @dw = left(DATENAME(DW, @date),1)

  declare @hr int
  set @hr = datepart(hour,@date)

  insert @tbl 
  select Top 1 --EffectiveStartDate, EffectiveEndDate, 
         CASE WHEN @dw = 'S' and (   (@hr between datepart(hour,weekenddaystart) and datepart(hour,weekenddayend) and isnull(weekenddaycost,0) <> 0)
                                  or (@hr NOT between datepart(hour,weekenddaystart) and datepart(hour,weekenddayend) and isnull(weekendnightcost,0) <> 0))
              THEN
                     CASE WHEN @hr between datepart(hour,weekenddaystart) and datepart(hour,weekenddayend)
                          THEN weekenddaycost
                          ELSE weekendnightcost
                     END
              ELSE 
                     CASE WHEN @hr between datepart(hour,weekdaystart) and datepart(hour,weekdayend)
                          THEN weekdaycost
                          ELSE weeknightcost
                     END
         END , climateChangeLevyRate, ((chargeablecapacity*capacityrate)),chargeablecapacity, isnull(StandingDayCharge,0)
  FROM   EnergySuiteDB.dbo.Rates
  where  UtilityName=@util 
  AND @date between EffectiveStartDate and EffectiveEndDate 
  Order By ID desc    -- get the "last" row that covers the requested date.

  if @@rowcount = 0
     insert @tbl 
     select Top 1 --EffectiveStartDate, EffectiveEndDate, 
         CASE WHEN @dw = 'S' and (   (@hr between datepart(hour,weekenddaystart) and datepart(hour,weekenddayend) and isnull(weekenddaycost,0) <> 0)
                                  or (@hr NOT between datepart(hour,weekenddaystart) and datepart(hour,weekenddayend) and isnull(weekendnightcost,0) <> 0))
              THEN
                     CASE WHEN @hr between datepart(hour,weekenddaystart) and datepart(hour,weekenddayend)
                          THEN weekenddaycost
                          ELSE weekendnightcost
                     END
              ELSE 
                     CASE WHEN @hr between datepart(hour,weekdaystart) and datepart(hour,weekdayend)
                          THEN weekdaycost
                          ELSE weeknightcost
                     END
         END , climateChangeLevyRate, ((chargeablecapacity*capacityrate)),chargeablecapacity, isnull(StandingDayCharge,0)
     FROM EnergySuiteDB.dbo.Rates
     where UtilityName=@util 
     order by EffectiveEndDate desc   -- highest enddate belongs to "row 1" the all covering / default rate.
  return 
END

Answer : Modify SP to get totals cross referenced against on/off hours

Maybe it's the div that's throwing things off.  On a web page, nothing really stands by itself.  Do you have before and after screen shots?  A link we can look at?
Random Solutions  
 
programming4us programming4us