SQL to calculate trailing sum based on partial data - sql

I have a few different footfall sensors across some stores.
Some sensors record footfall every 15min, others every 30min, and others every 60min. Not all stores have all sensors, and some data readings are missing.
The readings of the 60min sensor are the most accurate, followed by the 30min sensor, followed by the 15min.
I have this in a SQL table of the form:
sensorId
storeId
sensorType
readingTimeStamp
value
1
1
15m
2022-06-01 10:45
99
1
1
15m
2022-06-01 11:00
51
1
1
15m
2022-06-01 11:15
19
1
1
15m
2022-06-01 11:30
12
2
1
30m
2022-06-01 11:00
86
2
1
30m
2022-06-01 11:30
89
3
1
60m
2022-06-01 11:00
115
The task is to calculate the footfall in the last 60min every 15 minutes.
The logic is as follows:
If the last 60min are available from a 60min sensor use that
Else try to use the sum of two 30min sensors
Else try to use a 30min and two 15min sensors
Else try to use four of the 15min sensors
If we are not "on-the-hour" then build the reading starting from the last hourly measure
For example, at 11:45 the "best" way to calculate this is:
60min reading at 11:00 + 30min reading at 11:30 + 15min reading at 11:45 - 30min reading at 10:30 - 15min reading at 10:45
I have some Python code that does this fairly well. But any ideas on how to implement it in SQL?
*PS: this calculation is a business requirement. Also, it can't assume that two 15min readings add up to the 30min reading, etc...

Related

Calculate total manufacturing output over a shift for each location

We currently have a master table stored in our SQL server with the following example information:
Site
Shift Num
Start Time
End Time
Daily Target
A
1
8:00AM
4:00PM
10000
B
1
7:00AM
3:00PM
12000
B
2
4:00PM
2:00AM
7000
C
1
6:00AM
2:00PM
5000
As you can see, there are multiples sites each with their own respective shift start & end times as well as a total daily target for the day.
Another table in the DB is populated by users via the use of a PowerApp. This PowerApp will push output values to the server like so:
Site
Shift Number
Output
Timestamp
A
1
2500
3/15/2022 9:45 AM
A
1
4200
3/15/2022 11:15 AM
A
1
5600
3/15/2022 12:37 PM
A
1
7500
3/15/2022 2:15 PM
This table contains a log of all time-stamped output entries for each site / shift.
What I would like to do is do a daily trend of output vs. target. In order to do so, all output values over a specific shift would have to be aggregated in a SUM function for a given shift grouped by the shift day. The resulting view would need to look like this:
Site
Shift Number
Day
Actual
Target
A
1
3/14
9500
10000
B
1
3/14
13000
12000
A
1
3/15
8000
10000
B
1
3/15
10000
12000
This is easy enough for daytime shifts (group by day and sum the output values). However, if you notice in the master table, Site B / Shift 2 crosses midnight. In this example, I would need to sum values from the previous day 4PM up until 2AM of today. The date grouping would be done by the Shift End Time. Here's an example of the problem area:
Site
Shift Number
Output
Timestamp
B
2
3300
3/15/2022 5:45 PM
B
2
2200
3/15/2022 8:15 PM
B
2
1600
3/16/2022 12:37 AM
B
2
2500
3/16/2022 1:15 AM
I would need these four rows to be aggregated in the view as one row like so:
Site
Shift Number
Day
Actual
Target
B
2
3/16
9600
10000
The values should be listed under March 16th since the end time of the shift occurs then. The values are summated and the target is taken from the daily target master table.
How can I properly calculate these outputs for each shift every day irrespective if it crosses into a new day or not in a view? Or should I go a different route altogether?

how to use group by case in powerbuilder 10.5

date_entry time_start time_finished idle_code qty_good
8/8/2013 13:00 13:30 6 10
8/8/2013 13:30 15:20 0 20
8/8/2013 15:20 15:30 6 5
8/8/2013 15:30 16:25 0 10
8/8/2013 16:25 16:40 7 0
8/8/2013 16:40 17:25 0 40
8/8/2013 17:25 17:40 3 10
8/8/2013 17:40 24:00 1
8/8/2013 24:00 00:00 1
8/8/2013 00:00 00:30 1
Idle Time Legend:
0 Production
1 Adjustment/Mold
2 Machine
3 Quality Matter
4 Supply Matter
5 Mold Change
6 Replacer
7 Others
----------Result--------------------------------------
total mins
idle_code total mins
1 - 410:00 mins
2 - 00:00
3 - 15:00
4 - 00:00
5 - 00:00
6 - 40:00
7 - 15:00
0 - 210:00
First question how to group by idle_code and add the total mins.?
---------other report----------------------------------
production efficientcy report
idle_code total mins
1 410:00 mins
2 00:00 mins
3 15:00 mins
4 00:00 mins
5 00:00 mins
7 15:00 mins
total idle time = 440:00 mins (formula: sum(total mins of idle 1,2,3,4,5,7))
idle rate = 63.77% (formula: (total idle time / total actual production time)* 100 )
total operation time = 250:00 mins (formula sum(idl_code '0' and idle_code '6'))
machine efficienct = 36.23% (formula (total operation time / total actual production time * 100))
total actual production time = 690:00 mins (formula sum(total_idle_time + total operation time))
this is easy to compute in the powerbuilder using computed field but my problem is how to group them by idle_code and there total mins.
You could do this as a single SQL statement, summing the difference between the start and finish times, and grouping on idle_code. (Don't forget to make this a Left Outer Join from the Idle_Code table to the Production data table). This would save you from retrieving all the detail data to the client, and doing the grouping and summing there.
If you need to do this as a computed column, and you've retrieved all the detail data, then create a group on idle_code, and create a computed column that sums (time_finished - time_start for group 1). The SecondsAfter() function can do this, if those columns are datetimes and not just time values.
How are you storing your time_start and time_finished columns? Are those datetime datatypes? Because that makes the calculations much easier. If they're just times, you'll have problems calculating the duration when those times cross midnight into the next day.

SQL Query Turn field elements into columns

I have a table that looks like this
[Serial Number] [EventNumber] [DateTimeStamp] [DataElement] [DataValue]
XXXX1 1 7/7/2013 10:00 AM Height 62
XXXX1 1 7/7/2013 10:00 AM Mass 12
XXXX1 1 8/3/2013 3:00 PM Length 13
XXXX1 1 8/3/2013 3:00 PM Width 60
XXXX1 2 10/10/2013 10:00 AM Height 22
XXXX1 2 10/10/2013 10:00 AM Mass 21
XXXX1 2 10/12/2013 10:00 AM Length 7
XXXX1 2 10/12/2013 11:00 AM Width 67
Workers in the factory enter the data through a web interface and it ends up in this table. The table contains hundreds of serial numbers and each serial number can have up to 19 or more events. Each event is some parameters that are measured. After the measurements are taken some modifications are done and the measurements get taken again for a sequential event.
I would like to create a table that looks like this for one specific serial number through SQL query
[Serial Number] [EventNumber] [Height] [Mass] [Width] [Lenght]
XXXX1 1 62 12 13 20
XXXX1 2 10 etc etc
XXXX1 3 etc
XXXX1 4 etc
I know I need to use the pivot, but I can't necessarily come up with correct SQL code.
Note: The data used in this example is made up, but the structure is all the same.
Thanks in advance
try this:
TRANSFORM Sum(t.DataValue) AS SumOfDataValue
SELECT t.[Serial Number], t.EventNumber
FROM Table1 AS t
GROUP BY t.[Serial Number], t.EventNumber
PIVOT t.DataElement;
Let me know if any problems.

Sql query where condition based on fetched column value

I am making attendance system. I choose IN time for user for particular date using minimum time for the date and time greater than 4.00 AM. Now I want to find OUT time of user based on condition. Now OUT time can span across days. (because people work in night shift.). So condition for OUT time is maximum time of selected IN time plus 16 hours.
How can i write sql query for this?
My Database looks like this..
Name Time In-0/Out-1
Ajay 1.00 AM 4/12/2012 0
Ajay 6.00 AM 4/12/2012 1
Ajay 9.00 PM 4/12/2012 0 in time
Ajay 2.00 AM 5/12/2012 1
Ajay 2.15 AM 5/12/2012 0
Ajay 6.10 AM 5/12/2012 1 out time
I am fetching IN and OUT time for user. Some people work in night shift. So IN time is fetched as min of today's IN time which is greater than 4 AM. And OUT time needs to be fetched as Max time of today's out time which is less than of 16 hour added to today's IN time.

Design Hours of Operation SQL Table

I am designing a SQL table to store hours of operation for stores.
Some stores have very simple hours: Monday to Sunday from 9:30AM to 10:00PM
Others are little more complicated. Please consider the following scenario:
Monday: Open All Day
Tuesday: 7:30AM – 2:30PM & 4:15PM – 11:00 PM
Wednesday: 7:00PM – 12:30 AM (technically closing on Thursday morning)
Thursday: 9:00AM – 6:00PM
Friday: closed.
How would you design the table(s)?
EDIT
The hours will be used to showing if a store is open at a user selected time.
A different table can probably handle any exceptions, such as holidays.
The store hours will not change from week to week.
A table like this would be easy for both the output you posted, as well as just firing a bit back (open? yes/no):
Store | Day | Open | Closed
---------------------------
1 | 1 | 0000 | 2400
1 | 2 | 0730 | 1430
1 | 2 | 1615 | 2300
...
Features:
Using 24-hour isn't necessary, but makes math easier.
Store ID would presumably join to a lookup table where you stored Store information
Day ID would translate to day of week (1 = Sunday, 2 = Monday, etc.)
To query for your dataset, just:
SELECT Day, Open, Close... (you'd want to format Open/Close obviously)
To query IsOpen?, just:
SELECT CASE WHEN #desiredtime BETWEEN Open AND Closed THEN 1 ELSE 0 END
FROM table
WHERE store = #Store
Think of it more as defining time frames, days / weeks are more complex, because they have rules and defined start and stops.
How would you define a timeframe?
one constraint (Start[Time and Day]), one reference 'Duration' (hours, minutes,.. of the span)*. Now the shifts (timeframes) can span multiple days and you don't have to work complex logic to extract and use the data in calculations.
**Store_Hours**
Store | Day | Open | DURATION
---------------------------
1 | 1 | 0000 | 24
1 | 2 | 0730 | 7
1 | 2 | 1615 | 6.75
...
1 | 3 | 1900 | 5.5
Do you have to do more than just store and display it?
I think a design which needs to tell if a store is open at a particular time would have to be informed by all of the possibilities, otherwise, you will end up not being able to accommodate something.
What about holiday exceptions?
I would consider storing them as intervals based on a base time (minutes since time 0 on a week).
So 0 is midnight on Monday.
Interval 1 would be 0 - 1440
Interval 2 would be 1890 - 2310
etc.
You could easily convert a user selected time into a minute offset and determine if a store was open.
Your only problem remaining would be interpretation in display for friendly display (probably some extensive logic, but not impossible) and overlap at time 10080 -> 0.