SQL to Find records where result is in range between two columns, but check multiple rows - sql

I'm working with two datasets, one is a more detailed view of clock punch activity, and another is a summation of entire "shifts" that these clock punches make up. What we are trying to accomplish, is to return a record where the PAYCODEID is equal to '7' or '8' (these are meal break codes), and if it falls within the range of the last two columns in the entire shift table just below:
ClockEventShifts:
ShiftID EMPID Clockin MealRangeMax
1 00001280687 2014-02-16 08:00:00.000 2014-02-16 14:00:00.000
6 00001280687 2014-02-17 16:00:00.000 2014-02-17 22:00:00.000
There are a few key possibilities for the more detailed view of clock punches:
ClockEvent A:
EVENTID EMPID CLOCKIN CLOCKOUT PAYCODEID
228 00001280687 2014-02-16 08:00:00.000 2014-02-16 12:00:00.000 20
234 00001280687 2014-02-16 12:00:00.000 2014-02-16 13:00:00.000 8
235 00001280687 2014-02-16 13:00:00.000 2014-02-16 16:00:00.000 20
237 00001280687 2014-02-16 16:00:00.000 2014-02-16 17:01:00.000 21
238 00001280687 2014-02-16 17:01:00.000 2014-02-16 18:00:00.000 20
236 00001280687 2014-02-17 16:00:00.000 2014-02-17 17:00:00.000 20
ClockEvent B:
EVENTID EMPID CLOCKIN CLOCKOUT PAYCODEID
228 00001280687 2014-02-16 08:00:00.000 2014-02-16 12:00:00.000 20
234 00001280687 2014-02-16 12:00:00.000 2014-02-16 13:00:00.000 21
235 00001280687 2014-02-16 13:00:00.000 2014-02-16 16:00:00.000 20
237 00001280687 2014-02-16 16:00:00.000 2014-02-16 17:01:00.000 8
238 00001280687 2014-02-16 17:01:00.000 2014-02-16 18:00:00.000 20
236 00001280687 2014-02-17 16:00:00.000 2014-02-17 17:00:00.000 20
ClockEvent C:
EVENTID EMPID CLOCKIN CLOCKOUT PAYCODEID
228 00001280687 2014-02-16 08:00:00.000 2014-02-16 12:00:00.000 20
234 00001280687 2014-02-16 12:00:00.000 2014-02-16 13:00:00.000 21
235 00001280687 2014-02-16 13:00:00.000 2014-02-16 16:00:00.000 20
237 00001280687 2014-02-16 16:00:00.000 2014-02-16 17:01:00.000 21
238 00001280687 2014-02-16 17:01:00.000 2014-02-16 18:00:00.000 20
236 00001280687 2014-02-17 16:00:00.000 2014-02-17 17:00:00.000 20
ClockEvent D:
EVENTID EMPID CLOCKIN CLOCKOUT PAYCODEID
228 00001280687 2014-02-16 08:00:00.000 2014-02-16 12:00:00.000 20
234 00001280687 2014-02-16 12:00:00.000 2014-02-16 13:00:00.000 8
235 00001280687 2014-02-16 13:00:00.000 2014-02-16 16:00:00.000 20
237 00001280687 2014-02-16 16:00:00.000 2014-02-16 17:01:00.000 8
238 00001280687 2014-02-16 17:01:00.000 2014-02-16 18:00:00.000 20
236 00001280687 2014-02-17 16:00:00.000 2014-02-17 17:00:00.000 20
ClockEvent E:
EVENTID EMPID CLOCKIN CLOCKOUT PAYCODEID
228 00001280687 2014-02-16 08:00:00.000 2014-02-16 12:00:00.000 8
234 00001280687 2014-02-16 12:00:00.000 2014-02-16 13:00:00.000 21
235 00001280687 2014-02-16 13:00:00.000 2014-02-16 16:00:00.000 8
237 00001280687 2014-02-16 16:00:00.000 2014-02-16 17:01:00.000 21
238 00001280687 2014-02-16 17:01:00.000 2014-02-16 18:00:00.000 20
236 00001280687 2014-02-17 16:00:00.000 2014-02-17 17:00:00.000 20
Ideally, a perfect query/sproc could return the following in each scenario, checking for punches 360 minutes out:
A:
EVENTID EMPID CLOCKIN CLOCKOUT PAYCODEID
234 00001280687 2014-02-16 12:00:00.000 2014-02-16 13:00:00.000 8
B:
Nada!
C:
Nada!
D:
EVENTID EMPID CLOCKIN CLOCKOUT PAYCODEID
234 00001280687 2014-02-16 12:00:00.000 2014-02-16 13:00:00.000 8
E (it could return multiples too, but I really only care about the existence of at least one meal before 6 hours):
EVENTID EMPID CLOCKIN CLOCKOUT PAYCODEID
228 00001280687 2014-02-16 08:00:00.000 2014-02-16 12:00:00.000 8
It could also do something like this, ignoring that MealRangeMax piece and just using Clockin from ClockEventShifts:
A:
MINUTE_DIFFERENCE
240
B:
MINUTE_DIFFERENCE
600
C:
MINUTE_DIFFERENCE
NULL
D:
MINUTE_DIFFERENCE
240
600 (optional)
E:
MINUTE_DIFFERENCE
0
300 (optional)
I would tend to use something like IN or BETWEEN for such things, but IN can't check the values between things though to my knowledge, and BETWEEN can only check against an X and Y value to my knowledge, but I need to continue those BETWEEN checks for the rest of the result set from ClockEventShifts. I'm still searching for some solutions, but this seems to be slightly more complex.
Does anyone have any advice or ideas in approaching this problem?

This sql statement will give you records from CLOCKEVENT where the paycode is 7 or 8 and the event occurs within ClockEventShifts clockin time and mealrangemax.
SELECT ce.*
FROM ClockEvent ce
, ClockEventShifts ces
WHERE ce.PAYCODEID IN(7, 8)
AND ce.EMPID = ces.EMPID
AND ce.CLOCKIN >= ces.CLOCKIN
AND ce.CLOCKOUT <= ces.MealRangeMax
If you only care about the ClockIn time being within the ClockEventShift range of time, you could use this:
SELECT ce.*
FROM ClockEvent ce
, ClockEventShifts ces
WHERE ce.PAYCODEID IN(7, 8)
AND ce.EMPID = ces.EMPID
AND ce.CLOCKIN BETWEEN ces.CLOCKIN AND ces.MealRangeMax

Related

Update fields in table based on previous field records

I have a table of records for pay periods with fields WeekStart and WeekEnd populated for ever fiscal year. In my application a user should be able to update the first WeekEnd date for a given fiscal year and that should in turn update subsequent records WeekStart date by adding 1 day to the Previous WeekEnd date and for the same records's WeekEnd date, add 13 days to the new WeekStart date.
This is part of a Stored Procedure written in SQL Server 2016.
UPDATE [dbo].[staffing_BiweeklyPPCopy]
SET
[WeekStart] = DATEADD(DD, 1, LAG([WeekEnd], 1) OVER (ORDER BY [ID])),
[WeekEnd] = DATEADD(DD, 14, LAG([WeekEnd], 1) OVER (ORDER BY [ID]))
WHERE
[FiscalYear] = #fiscalyear
Original Table contents shown below...
ID WeekStart WeekEnd
163 2018-10-01 2018-10-13
164 2018-10-14 2018-10-27
165 2018-10-28 2018-11-10
166 2018-11-11 2018-11-24
167 2018-11-25 2018-12-08
168 2018-12-09 2018-12-22
169 2018-12-23 2019-01-05
170 2019-01-06 2019-01-19
171 2019-01-20 2019-02-02
172 2019-02-03 2019-02-16
173 2019-02-17 2019-03-02
174 2019-03-03 2019-03-16
175 2019-03-17 2019-03-30
176 2019-03-31 2019-04-13
177 2019-04-14 2019-04-27
178 2019-04-28 2019-05-11
179 2019-05-12 2019-05-25
180 2019-05-26 2019-06-08
181 2019-06-09 2019-06-22
182 2019-06-23 2019-07-06
183 2019-07-07 2019-07-20
184 2019-07-21 2019-08-03
185 2019-08-04 2019-08-17
186 2019-08-18 2019-08-31
187 2019-09-01 2019-09-14
188 2019-09-15 2019-09-28
189 2019-09-29 2019-09-30
For example if a user updates the weekend date for record ID 163 to '2018-10-14', the table will update as follows..
ID WeekStart WeekEnd
163 2018-10-01 2018-10-14
164 2018-10-15 2018-10-28
165 2018-10-29 2018-11-11
166 2018-11-12 2018-11-25
167 2018-11-26 2018-12-09
.
.
.
189 2019-09-30 2019-09-30
Thank you in advance.

MSSQL MAX returns all results?

I have tried the following query to return the highest P.Maxvalue for each ME.Name from the last day between 06:00 and 18:00:
SELECT MAX(P.MaxValue) AS Value,P.DateTime,ME.Name AS ID
FROM vManagedEntity AS ME INNER JOIN
Perf.vPerfHourly AS P ON ME.ManagedEntityRowId = P.ManagedEntityRowId INNER JOIN
vPerformanceRuleInstance AS PRI ON P.PerformanceRuleInstanceRowId = PRI.PerformanceRuleInstanceRowId INNER JOIN
vPerformanceRule AS PR ON PRI.RuleRowId = PR.RuleRowId
WHERE (ME.ManagedEntityTypeRowId = 2546) AND (pr.ObjectName = 'VMGuest-cpu') AND (pr.CounterName LIKE 'cpuUsageMHz') AND (CAST(p.DateTime as time) >= '06:00:00' AND CAST(p.DateTime as time) <='18:00:00') AND (p.DateTime > DATEADD(day, - 1, getutcdate()))
group by ME.Name,P.DateTime
ORDER by id
but it seems to return each MaxValue for each ID instead of the highest?
like:
Value DateTime ID
55 2018-02-19 12:00:00.000 bob:vm-100736
51 2018-02-19 13:00:00.000 bob:vm-100736
53 2018-02-19 14:00:00.000 bob:vm-100736
52 2018-02-19 15:00:00.000 bob:vm-100736
52 2018-02-19 16:00:00.000 bob:vm-100736
51 2018-02-19 17:00:00.000 bob:vm-100736
54 2018-02-19 18:00:00.000 bob:vm-100736
51 2018-02-20 06:00:00.000 bob:vm-100736
51 2018-02-20 07:00:00.000 bob:vm-100736
53 2018-02-20 08:00:00.000 bob:vm-100736
52 2018-02-20 09:00:00.000 bob:vm-100736
78 2018-02-19 12:00:00.000 bob:vm-101
82 2018-02-19 13:00:00.000 bob:vm-101
79 2018-02-19 14:00:00.000 bob:vm-101
78 2018-02-19 15:00:00.000 bob:vm-101
79 2018-02-19 16:00:00.000 bob:vm-101
77 2018-02-19 17:00:00.000 bob:vm-101
82 2018-02-19 18:00:00.000 bob:vm-101
82 2018-02-20 06:00:00.000 bob:vm-101
79 2018-02-20 07:00:00.000 bob:vm-101
81 2018-02-20 08:00:00.000 bob:vm-101
82 2018-02-20 09:00:00.000 bob:vm-101
155 2018-02-19 12:00:00.000 bob:vm-104432
there is one value per hour for each id hence twelve results for each id
does MAX not work in this way i want ?
Thanks
expected view like this :
Value DateTime ID
55 2018-02-19 12:00:00.000 bob:vm-100736
82 2018-02-19 13:00:00.000 bob:vm-101
etc
If you're using group by on datetime and id, you'll get all datetimes and all ids, it's that simple.
If you don't need exact time, you can group by date only:
SELECT MAX(P.MaxValue) AS Value, cast(P.DateTime as date) as dat, ME.Name AS ID
...
group by ME.Name, cast(P.DateTime as date)
Or if you do, you may use not exists clause instead of group by.

TSQL - Creating a consolidated schedule from contiguous schedule parts

I am having the absolute worst time trying to consolidate a list of schedule parts into a more concise list when start and end times match. The code below is for a single schedule, and the code is a reference to what is happening at that time for the user.
Any thoughts would be greatly appreciated!
declare #t as table (code int, dtDate DateTime, dtStart DateTime, dtEnd DateTime)
insert into #t values
(46,'2017-01-23','2017-01-23 06:00','2017-01-23 14:45'),
(127,'2017-01-23','2017-01-23 07:30','2017-01-23 08:00'),
(127,'2017-01-23','2017-01-23 08:00','2017-01-23 08:15'),
(127,'2017-01-23','2017-01-23 08:15','2017-01-23 10:00'),
(76,'2017-01-23','2017-01-23 10:00','2017-01-23 10:45'),
(127,'2017-01-23','2017-01-23 10:45','2017-01-23 13:00'),
(127,'2017-01-23','2017-01-23 13:00','2017-01-23 13:15'),
(127,'2017-01-23','2017-01-23 13:15','2017-01-23 14:30')
select * from #t
-- Current Output
code dtDate dtStart dtEnd
----------- ----------------------- ----------------------- -----------------------
46 2017-01-23 00:00:00.000 2017-01-23 06:00:00.000 2017-01-23 14:45:00.000
127 2017-01-23 00:00:00.000 2017-01-23 07:30:00.000 2017-01-23 08:00:00.000
127 2017-01-23 00:00:00.000 2017-01-23 08:00:00.000 2017-01-23 08:15:00.000
127 2017-01-23 00:00:00.000 2017-01-23 08:15:00.000 2017-01-23 10:00:00.000
76 2017-01-23 00:00:00.000 2017-01-23 10:00:00.000 2017-01-23 10:45:00.000
127 2017-01-23 00:00:00.000 2017-01-23 10:45:00.000 2017-01-23 13:00:00.000
127 2017-01-23 00:00:00.000 2017-01-23 13:00:00.000 2017-01-23 13:15:00.000
127 2017-01-23 00:00:00.000 2017-01-23 13:15:00.000 2017-01-23 14:30:00.000
-- Expected Output
code dtDate dtStart dtEnd
----------- ----------------------- ----------------------- -----------------------
46 2017-01-23 00:00:00.000 2017-01-23 06:00:00.000 2017-01-23 14:45:00.000
127 2017-01-23 00:00:00.000 2017-01-23 07:30:00.000 2017-01-23 10:00:00.000
76 2017-01-23 00:00:00.000 2017-01-23 10:00:00.000 2017-01-23 10:45:00.000
127 2017-01-23 00:00:00.000 2017-01-23 10:45:00.000 2017-01-23 14:30:00.000
Looks like a classic Gaps & Islands
Select Code
,dtDate
,dtStart = min(dtStart)
,dtEnd = max(dtEnd)
From (
Select *
,Grp = Row_Number() over (Partition By Code,dtDate Order By dtStart) - Row_Number() over (Order by dtEnd)
From #t
) A
Group By Code,dtDate,Grp
Order By min(dtStart)
Returns

SQL Aggregate Woes

I have this code:
SELECT q.HospitalNumber, q.Patient_Name,
q.[Date/Time]) as DATE_OF_GCS, --convert(varchar(5),q.[Date/Time],108) as TIME_OF_GCS,
max(q.[GCS_COUNT]) as BEST_GCS
From
(
Select pat.HospitalNumber, pat.FirstName + ' ' + pat.LastName as Patient_Name, ts.Time as [Date/Time], sum(pt.value) as [GCS_COUNT]
from ParametersText pt INNER JOIN TextSignals ts ON ts.TextID = pt.TextID AND ts.ParameterID = pt.ParameterID
INNER JOIN Patients pat ON pat.patientID = ts.PatientID
WHERE ts.ParameterID = 21654 or ts.ParameterID = 21655 or ts.ParameterID = 21656
GROUP BY pat.HospitalNumber, pat.FirstName, pat.LastName, ts.PatientID, ts.Time
) q
GROUP BY q.HospitalNumber, q.Patient_Name, q.[Date/Time]
--,convert(varchar(5),q.[Date/Time],108)
But all I'm after is the highest Best_GCS per day per patient, but I need the time as well. The recording of the GCS can occur many times of the day and can be the same score several times. Any help would be most appreciated...
Thanks very much in advance...
This is on SQL Server (t-sql)
Here is a snippet of the data this query throws out:
patientID Patient_Name DATE_OF_GCS GCS
442 patient name 2014-02-13 16:00:00.000 15
442 patient name 2014-02-13 18:00:00.000 15
442 patient name 2014-02-13 20:00:00.000 15
442 patient name 2014-02-14 00:00:00.000 15
442 patient name 2014-02-14 04:00:00.000 15
442 patient name 2014-02-14 05:00:00.000 15
442 patient name 2014-02-14 06:00:00.000 15
442 patient name 2014-02-14 08:00:00.000 15
442 patient name 2014-02-14 12:00:00.000 15
442 patient name 2014-02-14 16:00:00.000 15
442 patient name 2014-02-14 17:00:00.000 15
442 patient name 2014-02-14 20:00:00.000 15
442 patient name 2014-02-14 23:00:00.000 15
442 patient name 2014-02-15 00:00:00.000 15
442 patient name 2014-02-15 02:00:00.000 15
442 patient name 2014-02-15 05:00:00.000 15
442 patient name 2014-02-15 08:00:00.000 15
442 patient name 2014-02-15 12:00:00.000 15
442 patient name 2014-02-15 15:00:00.000 11
442 patient name 2014-02-15 16:00:00.000 15
442 patient name 2014-02-15 17:00:00.000 15
442 patient name 2014-02-15 18:00:00.000 15
442 patient name 2014-02-15 20:00:00.000 15
442 patient name 2014-02-16 00:00:00.000 15
442 patient name 2014-02-16 02:00:00.000 15
442 patient name 2014-02-16 05:00:00.000 15
442 patient name 2014-02-16 08:00:00.000 15
442 patient name 2014-02-16 20:00:00.000 11
442 patient name 2014-02-16 20:51:00.000 4
442 patient name 2014-02-17 01:00:00.000 15
442 patient name 2014-02-17 02:00:00.000 15
442 patient name 2014-02-17 04:00:00.000 15
442 patient name 2014-02-17 06:00:00.000 15
442 patient name 2014-02-17 08:00:00.000 15
442 patient name 2014-02-17 10:00:00.000 15
442 patient name 2014-02-17 15:00:00.000 15
442 patient name 2014-02-17 18:00:00.000 15
442 patient name 2014-02-17 20:00:00.000 15
442 patient name 2014-02-18 00:00:00.000 15
442 patient name 2014-02-18 04:00:00.000 15
442 patient name 2014-02-18 08:00:00.000 15
442 patient name 2014-02-18 12:00:00.000 15
442 patient name 2014-02-18 14:00:00.000 15
442 patient name 2014-02-18 15:00:00.000 15
442 patient name 2014-02-18 17:00:00.000 15
442 patient name 2014-02-18 19:00:00.000 15
442 patient name 2014-02-18 20:00:00.000 11
442 patient name 2014-02-19 02:00:00.000 15
442 patient name 2014-02-19 06:00:00.000 15
442 patient name 2014-02-19 09:00:00.000 15
471 patient name 2014-02-13 09:00:00.000 7
471 patient name 2014-02-13 11:00:00.000 7
471 patient name 2014-02-13 13:00:00.000 7
471 patient name 2014-02-13 15:00:00.000 8
471 patient name 2014-02-13 17:00:00.000 8
471 patient name 2014-02-13 19:00:00.000 7
471 patient name 2014-02-13 21:00:00.000 5
471 patient name 2014-02-13 22:00:00.000 5
471 patient name 2014-02-14 00:00:00.000 5
471 patient name 2014-02-14 02:00:00.000 5
471 patient name 2014-02-14 04:00:00.000 5
471 patient name 2014-02-14 06:00:00.000 5
471 patient name 2014-02-14 08:00:00.000 9
471 patient name 2014-02-14 10:00:00.000 6
471 patient name 2014-02-14 12:00:00.000 6
471 patient name 2014-02-14 14:00:00.000 8
471 patient name 2014-02-14 16:00:00.000 6
471 patient name 2014-02-14 18:00:00.000 6
471 patient name 2014-02-14 20:00:00.000 5
471 patient name 2014-02-14 22:00:00.000 6
471 patient name 2014-02-15 00:00:00.000 6
471 patient name 2014-02-15 02:00:00.000 6
471 patient name 2014-02-15 04:00:00.000 6
471 patient name 2014-02-15 06:00:00.000 6
471 patient name 2014-02-15 08:00:00.000 8
471 patient name 2014-02-15 09:00:00.000 6
471 patient name 2014-02-15 10:00:00.000 6
471 patient name 2014-02-15 11:00:00.000 3
471 patient name 2014-02-15 13:00:00.000 5
471 patient name 2014-02-15 14:00:00.000 3
471 patient name 2014-02-15 16:00:00.000 3
471 patient name 2014-02-15 18:00:00.000 3
471 patient name 2014-02-15 19:00:00.000 3
471 patient name 2014-02-15 21:00:00.000 3
471 patient name 2014-02-15 22:00:00.000 3
471 patient name 2014-02-16 00:00:00.000 3
471 patient name 2014-02-16 02:00:00.000 3
471 patient name 2014-02-16 02:30:00.000 3
471 patient name 2014-02-16 03:00:00.000 3
471 patient name 2014-02-16 06:00:00.000 3
471 patient name 2014-02-16 08:00:00.000 3
471 patient name 2014-02-16 12:00:00.000 5
471 patient name 2014-02-16 14:00:00.000 3
471 patient name 2014-02-16 18:00:00.000 3
471 patient name 2014-02-16 19:00:00.000 3
471 patient name 2014-02-16 21:00:00.000 3
472 patient name 2014-02-13 08:00:00.000 15
472 patient name 2014-02-13 12:00:00.000 15
472 patient name 2014-02-13 15:00:00.000 15
472 patient name 2014-02-13 19:00:00.000 15
472 patient name 2014-02-13 22:00:00.000 15
472 patient name 2014-02-14 03:00:00.000 15
472 patient name 2014-02-14 08:00:00.000 15
472 patient name 2014-02-14 14:00:00.000 15
472 patient name 2014-02-14 17:00:00.000 15
472 patient name 2014-02-14 19:00:00.000 15
472 patient name 2014-02-14 21:00:00.000 15
472 patient name 2014-02-14 23:00:00.000 15
472 patient name 2014-02-15 01:00:00.000 15
472 patient name 2014-02-15 05:00:00.000 14
472 patient name 2014-02-15 07:00:00.000 15
472 patient name 2014-02-15 08:00:00.000 15
472 patient name 2014-02-15 20:00:00.000 15
472 patient name 2014-02-15 22:00:00.000 15
472 patient name 2014-02-16 00:00:00.000 15
472 patient name 2014-02-16 03:00:00.000 15
472 patient name 2014-02-16 05:00:00.000 15
472 patient name 2014-02-16 07:00:00.000 15
472 patient name 2014-02-16 09:00:00.000 15
472 patient name 2014-02-16 12:00:00.000 15
472 patient name 2014-02-16 15:00:00.000 15
472 patient name 2014-02-16 18:00:00.000 15
472 patient name 2014-02-16 20:00:00.000 15
472 patient name 2014-02-16 22:00:00.000 15
472 patient name 2014-02-17 00:00:00.000 15
472 patient name 2014-02-17 02:00:00.000 15
472 patient name 2014-02-17 04:00:00.000 15
I figured it out. Thanks Anyway..
Here's the code. If there's any way it could be better, I'd love to hear it:
With t as
(
SELECT q.HospitalNumber, q.Patient_Name,
q.[Date/Time] as DATE_OF_GCS,
max(q.[GCS_COUNT]) as BEST_GCS
From
(
Select pat.HospitalNumber, pat.FirstName + ' ' + pat.LastName as Patient_Name, ts.Time as [Date/Time], sum(pt.value) as [GCS_COUNT]
from ParametersText pt INNER JOIN TextSignals ts ON ts.TextID = pt.TextID AND ts.ParameterID = pt.ParameterID
INNER JOIN Patients pat ON pat.patientID = ts.PatientID
WHERE ts.ParameterID = 21654 or ts.ParameterID = 21655 or ts.ParameterID = 21656
GROUP BY pat.HospitalNumber, pat.FirstName, pat.LastName, ts.PatientID, ts.Time
) q
GROUP BY q.HospitalNumber, q.Patient_Name, q.[Date/Time]
)
Select hospitalnumber, Date_Of_GCS, Best_GCS
FROM (
select t.hospitalnumber, t.Date_Of_GCS, t.Best_GCS, ROW_NUMBER() over (partition by t.hospitalnumber, cast(t.Date_Of_GCS as date) order by t.Best_GCS Desc ) as GCS
FROM t ) as p
where gcs = 1
Order By hospitalnumber, Date_Of_GCS

How do you time weight average data between two dates for any desired interval in Microsoft SQL Server 2014 Express?

I am trying to write a SQL call that will time weight average data in any desired interval. This meaning i only have to change a few parameters inside the query so the final output will be in Day's, Hours and or minutes between my two desired dates.
I also need it to fill in data between missing intervals like this Example
Actual DataBase Data
Time_Stamp Time_Stamp_ms BPS_FIT0161
2014-07-26 22:32:36 74 164
2014-07-26 22:32:37 71 164
2014-07-26 22:32:38 71 164
2014-07-26 22:32:39 70 162
2014-07-26 22:32:40 71 162
2014-07-26 22:32:41 67 162
2014-07-26 22:32:42 64 165
2014-07-26 22:32:43 63 164
2014-07-26 22:32:44 62 164
2014-07-26 22:32:45 63 163
2014-07-26 22:32:46 59 163
2014-07-26 22:32:47 56 165
2014-07-26 22:32:48 55 167
2014-07-26 22:32:49 54 167
2014-07-26 22:32:50 54 168
2014-07-26 22:32:51 51 168
2014-07-26 22:32:52 47 171
2014-07-26 22:32:53 46 173
2014-07-26 22:32:54 111 177
2014-07-26 22:32:55 42 178
2014-07-26 22:38:56 99 178
2014-07-26 23:24:57 426 178
2014-07-27 00:21:58 854 178
2014-07-27 01:53:09 229 178
2014-07-27 03:30:11 419 178
2014-07-27 05:25:14 56 178
2014-07-27 07:32:16 881 178
2014-07-27 09:48:20 48 178
2014-07-27 12:55:24 286 178
2014-07-27 16:13:28 562 178
2014-07-27 20:10:33 803 178
2014-07-28 00:56:40 26 178
2014-07-28 06:38:47 753 178
2014-07-28 08:38:47 753 178
2014-07-28 09:24:37 219 248
2014-07-28 09:24:38 218 248
2014-07-28 09:24:39 214 226
2014-07-28 09:24:40 212 226
2014-07-28 09:24:41 212 226
2014-07-28 09:24:42 208 224
2014-07-28 09:24:43 207 222
2014-07-28 09:24:44 206 222
2014-07-28 09:24:45 206 222
2014-07-28 10:11:45 604 202
SQL Time Weighted Average (TWA) Hourly query should look something like this:
Date_time BPS_FIT0161 TWA
2014-07-26 22:00:00 177.4342105
2014-07-26 23:00:00 178
2014-07-27 00:00:00 178
2014-07-27 01:00:00 178
2014-07-27 02:00:00 178
2014-07-27 03:00:00 178
2014-07-27 04:00:00 178
2014-07-27 05:00:00 178
2014-07-27 06:00:00 178
2014-07-27 07:00:00 178
2014-07-27 08:00:00 178
2014-07-27 09:00:00 178
2014-07-27 10:00:00 178
2014-07-27 11:00:00 178
2014-07-27 12:00:00 178
2014-07-27 13:00:00 178
2014-07-27 14:00:00 178
2014-07-27 15:00:00 178
2014-07-27 16:00:00 178
2014-07-27 17:00:00 178
2014-07-27 18:00:00 178
2014-07-27 19:00:00 178
2014-07-27 20:00:00 178
2014-07-27 21:00:00 178
2014-07-27 22:00:00 178
2014-07-27 23:00:00 178
2014-07-28 00:00:00 178
2014-07-28 01:00:00 178
2014-07-28 02:00:00 178
2014-07-28 03:00:00 178
2014-07-28 04:00:00 178
2014-07-28 05:00:00 178
2014-07-28 06:00:00 178
2014-07-28 07:00:00 178
2014-07-28 08:00:00 178
2014-07-28 09:00:00 179.5349202
2014-07-28 10:00:00 202.0857852
Thank you so much for your help!
http://sqlfiddle.com/#!6/a8db7/1
End of my question
Beginning of solutions
Using VKP's Solution
SELECT dateadd(hour, datediff(hour, 0, Time_Stamp),0) as Date_Time,
sum(time_stamp_ms * bps_fit0161)/sum(time_stamp_ms) as weighted_avg
FROM BPS
WHERE Time_Stamp BETWEEN CONVERT(DATETIME, '2014-07-26 00:00:00', 102)
AND CONVERT(DATETIME, '2014-07-30 00:00:00', 102)
group by dateadd(hour, datediff(hour, 0, Time_Stamp),0),
dateadd(day,datediff(day, 0, Time_Stamp),0)
order by dateadd(hour, datediff(hour, 0, Time_Stamp),0),
dateadd(day,datediff(day, 0, Time_Stamp),0)
My Query's Result
Date_Time weighted_avg
2014-07-26 00:00:00.000 180
2014-07-26 01:00:00.000 113
2014-07-26 02:00:00.000 147
2014-07-26 03:00:00.000 221
2014-07-26 04:00:00.000 252
2014-07-26 05:00:00.000 379
2014-07-26 06:00:00.000 370
2014-07-26 07:00:00.000 253
2014-07-26 08:00:00.000 125
2014-07-26 09:00:00.000 119
2014-07-26 10:00:00.000 125
2014-07-26 11:00:00.000 117
2014-07-26 12:00:00.000 160
2014-07-26 13:00:00.000 123
2014-07-26 14:00:00.000 86
2014-07-26 15:00:00.000 81
2014-07-26 16:00:00.000 100
2014-07-26 17:00:00.000 108
2014-07-26 18:00:00.000 175
2014-07-26 19:00:00.000 238
2014-07-26 20:00:00.000 211
2014-07-26 21:00:00.000 231
2014-07-26 22:00:00.000 173
2014-07-26 23:00:00.000 178
2014-07-27 00:00:00.000 178
2014-07-27 01:00:00.000 178 <----- Start of missing Data!
2014-07-27 03:00:00.000 178
2014-07-27 05:00:00.000 178
2014-07-27 07:00:00.000 178
2014-07-27 09:00:00.000 178
2014-07-27 12:00:00.000 178
2014-07-27 16:00:00.000 178
2014-07-27 20:00:00.000 178
2014-07-28 00:00:00.000 178
2014-07-28 06:00:00.000 178
2014-07-28 09:00:00.000 160
2014-07-28 10:00:00.000 134
2014-07-28 11:00:00.000 113
2014-07-28 12:00:00.000 136
2014-07-28 13:00:00.000 131
2014-07-28 14:00:00.000 84
2014-07-28 15:00:00.000 102
As you can see I am missing hours due to our database being offline or wireless nodes on my network losing communication. What would you change in the above query to auto fill missing hours with the previous hours data, the same goes for missing data for days.
http://sqlfiddle.com/#!6/a8db7/31/0
declare #s datetime
declare #e datetime
set #s = '2014-07-26 00:00:00'
set #e = '2014-07-30 00:00:00'
;with x(n) as
(
SELECT TOP (DATEDIFF(HOUR, #s, #e) + 1)
rn = ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.all_columns ORDER BY [object_id]
)
select DATEADD(HOUR, n-1, #s) as dt into t from x
;with y as (
SELECT
row_number() over(order by t.dt) as rn,
t.dt,
sum(time_stamp_ms * bps_fit0161) / sum(time_stamp_ms) as weighted_avg
FROM BPS
right join t on t.dt = dateadd(hour, datediff(hour, 0, Time_Stamp),0)
group by t.dt,dateadd(hour, datediff(hour, 0, Time_Stamp),0)
)
select y.dt ,
case when y.weighted_avg is null then prev_y.weighted_avg
else y.weighted_avg end as weighted_avg
from y
left join y prev_y on y.rn = prev_y.rn-1
Try this. This groups by the start of any hour till the end of that hour.
Edited: To include all the hours between specified times. This may get you closer to what you are looking for.