db: ms sql server 11.0.3156.
i have table record periodic data values. key columns are: fldobjectguid (varchar), flddatatimestamp (datetime), fldconfigitem (varchar), fldconfigitemvalue (numeric)
i want retrieve data different time frame (day, week, month). keep number of returned data pints manageable number (e.g. less < 350), therefore, i'd averages.
for example:
- day - return data (already got this!)
- week - return data in hourly average values (e.g. there 24 * 1 hour averages, * 7 days)
- month - return data in 3-hourly average values (e.g. 8 * average on 3 hours, * 30)
- yearly - return data in daily average values (e.g. 1 * average on 24 hours, * 365)
a small example of data set shown here:
+--------------------------------------------------------------------------------+ + fldobjectguid | fldrecordupdatedtimestamp | fldconfigitem | fldconfigitemvalue | + 40010000 | 2015-06-16 18:20:48.000 | icmpresponsetime | 4.00 | + 40010000 | 2015-06-16 19:22:00.000 | icmpresponsetime | 15.00 | + 40010000 | 2015-06-16 20:22:14.000 | icmpresponsetime | 4.00 | + 40010000 | 2015-06-17 17:35:19.000 | icmpresponsetime | 6.00 | + 40010000 | 2015-06-17 18:36:26.000 | icmpresponsetime | 4.00 | + 40010000 | 2015-06-28 02:18:31.000 | icmpresponsetime | 19.00 | + 40010000 | 2015-06-28 03:18:54.000 | icmpresponsetime | 9.00 | + 40010000 | 2015-06-02 17:25:16.000 | icmpresponsetime | 3.00 | +------------------------------------------------------------------------------------+
data added object (fldobjectguid) @ different rates. 1 row every 5 minutes or 1 one row every hour. there can gaps in data (hours or days). want graph fldconfigitemvalue data each object on different time frames; day (last 24 hours), week, month , year. periods of returned data don't need exact. so, month last 30 days, or 1 calendar month today's date.
the sql needs return data single fldobjectguid , fldconfigitem combination - i'll amend sql @ run-time data required object/configitem.
there may gaps in data, no data points within given period. so, return value can zero.
i'm retrieving data using classic asp, creating sql statement , parsing results. achieve result programatically in asp code. 'week' required set, make repeated calls db, using average function, , clause retrieve subset of records (now - 1 hour). store value, repeat using clause (now - 1 hour - 2 hours). , step in time until i've got values week. 'month' , 'yearly' routines same, different timeframes in clauses.
however, me, seems clumsy way of doing , 1 sql routine (or different sql routine week, month , year) must quicker , / or more elegant.
at moment, have sql (from stackoverflow?) thought might work , have code build sql 'month' view (i've hard-coded fldobjectguid , fldconfigitem in example, make example clearer):
select top 30 convert(date, l.flddatatimestamp) 'flddatatimestamp_result', l.fldconfigitemvalue, l.fldconfigitemvalue tblobjecthealthcheckdata_historic l inner join ( select min(flddatatimestamp) first_timestamp tblobjecthealthcheckdata_historic fldobjectguid = '10050400' , fldconfigitem = 'availableram' group convert(date, flddatatimestamp) ) sub_l on (sub_l.first_timestamp = l.flddatatimestamp) fldobjectguid = '10050400' , l.fldconfigitem = 'availableram' order flddatatimestamp desc
but gets first data point each day (as can guess, whilst understand sql , programming, hobby, not living) , i'm struggling fix code.
i'm assuming people agree, it's more efficient doing in code making many separate sql calls - can help?
i try datepart function, way can different parts of fldrecordupdatedtimestamp , avg field fldconfigitemvalue.
this goes down single hour of timestamp (could minutes, check msdn datepart in t-sql), if wish daily averages per week need include:
day_fldrecordupdatedtimestamp week_fldrecordupdatedtimestamp
this average each day inside each week.
below example shows average per month - mind year, if have more years worth of data make sure include year_fldrecordupdatedtimestamp etc.
with partstable ( select fldobjectguid , fldrecordupdatedtimestamp , fldconfigitem , fldconfigitemvalue , datepart(hour, fldrecordupdatedtimestamp) hour_fldrecordupdatedtimestamp , datepart(day, fldrecordupdatedtimestamp) day_fldrecordupdatedtimestamp , datepart(week, fldrecordupdatedtimestamp) week_fldrecordupdatedtimestamp , datepart(month, fldrecordupdatedtimestamp) month_fldrecordupdatedtimestamp , datepart(year, fldrecordupdatedtimestamp) year_fldrecordupdatedtimestamp yourlogtable --where -- perhaps set limit here not huge set in first step. ) select count(1) setcount /* shows how many rows in each avg calculation. */ , fldobjectguid , fldconfigitem , month_fldrecordupdatedtimestamp /* change column specific span you're intrested in. */ , avg(fldconfigitemvalue) avg_fldconfigitemvalue partstable group fldobjectguid , fldconfigitem , month_fldrecordupdatedtimestamp /* change column specific span you're intrested in. */ ;
one final note: make sure include month_, week_ etc. column in both select , group by.
Comments
Post a Comment