Tracking workload over time - tsql

I have a work database that lists:
Type of job
Date job started
Date job finished
I have been asked if I can produce a report that can be run each Monday (or whenever) that:
a) shows the current workload and
b) shows what the workload was the previous week (and each previous week of the current financial year - 1/4/18 - 31/3/19).
Its date parameters would be:
week 1: 1/4/18 - 7/4/18
week 2: 8/4/18 - 15/4/18 etc
so I would be looking at live workload totals as at 1/4/18, 8/4/18 etc
If there is no date in the 'date job finished' field then a job is considered live.
So for example if we look at these 4 jobs:
job 1 started 31/3/18 finished 21/4/18
job 2 started 2/4/18 finished 20/4/18
job3 started 6/4/18 unfinished
and job 4 start on 10/4/18 unfinished
And ran a report on 22/4/18 I would need its output to be, sowing what the workload was on these weeks:
Workload:
Week 1(1/4/18) 3
Week 2 (8/4/18) 3
Week 3 4
Week 4 2
3 3 4 2
So in terms of current workload - that's easy and just a count of jobs where the 'date job finished' field is null.
However I'm struggling to work out how to calculate the workload over time - basically I need a query to work out how to get an accurate count of when the date job finished field was null in a particular week.
Any help / assistance would be massively appreciated.
Thanks.

My solution based on my understanding of your problem
DECLARE #t TABLE ( JobType NVARCHAR(50), JobStart DATETIME, JobFinish DATETIME )
INSERT INTO #t
(JobType,JobStart, JobFinish)
VALUES
('Type1', '20180604', '20180611')
,('Type2', '20180611', '20180626')
,('Type3', '20180618', '20180620')
,('Type4', '20180625', NULL)
/*
Week Date Ranges
1. 04062018 to 10062018
2. 11062018 to 17062018
3. 18062018 to 24062018
4. 25062018 to 01072018
*/
--To calculate finished jobs that were Started in Week 1 04062018 to 10062018 and finished after this week
SELECT
T.JobType
,T.JobStart
,T.JobFinish
FROM #t T
WHERE (T.JobStart >= '20180604' AND T.JobStart <= '20180610') AND T.JobFinish > '20180610'
output
JobType JobStart JobFinish
Type1 2018-06-04 00:00:00.000 2018-06-11 00:00:00.000

Related

How to find the week number per current month in PostgreSQL?

My working environment
PostgreSQL version: 10.9 (64 bits)
OS: Windows 10 (64 bits)
I need to find the week number of a given date in the current month. So unlike the ISO week number which is computed from the beginning of the year, here the computation is done from the beginning of the current month and therefore the result is a number between 1 and 5. Here are a few examples for June 2020:
Date in the current month Week number per current month
========================== ===============================
2020-06-01 -----> 1
2020-06-10 -----> 2
2020-06-19 -----> 3
2020-06-23 -----> 4
2020-06-23 -----> 5
I was reading the online documentation: Date/Time Functions and Operators It seems that there is no function providing directly what I'm looking for. So after a few successful tests, here is the solution that I found:
select
extract('week' from current_date) -
extract('week' from date_trunc('month', current_date))
+ 1;
I consider myself to be rather a beginner in using date functions, so just to make sure that I'm on the right track, do you think that this solution is correct? As I said, after a few tests it seems to me that it gets the job done.
The to_char() method offers such a feature:
W - week of month (1-5) (the first week starts on the first day of the month)
select to_char(current_date, 'W');
It returns a string value, but that can easily be cast to a number.

how to find number of days since 28th of last month till 27th of current month in db2

I need to generate a report on 28th of every month .
So for that I need to run an autosys job.
In that I have a query with the condition
validation_date >= (number of days since last run)
Could you please help me on this .How can I achieve this condition in DB2 ?
This is a monthly job.So I don't want to hard code my previous run date in the query .At the same time I need to get a condition which satisfies for all the months .
Note :
If the query is running on feb 28th ,then feb 28th is not included. I need to get data from january 28th(included) till feb 27th(included)
similarly for march 28th run ,I need to get data from feb 28th(included) till march 27th(included)...Thanks in advance.Please help
Consider putting your report generation in a procedure, and parameterizing the start and end dates. In other words, have something like this:
create procedure monthly_report(
start_date date,
end_date date
)
language sql
begin
... report queries here ...
end
Now you potentially have something much more flexible (depending on the report requirements). If, in the future, you want to run a report on a different day, or for a different length of time, you will be able to do that.
Once you design it this way, it also may be easier to set the dates in your job scheduling script, rather than in SQL. If you did it in SQL, you could do something like this:
call monthly_report(
(select
year(current timestamp - 2 months) ||'-'||
month(current timestamp - 2 months) ||'-'||
'28' from sysibm.sysdummy1
),
(select
year(current timestamp - 1 month) ||'-'||
month(current timestamp - 1 month) ||'-'||
'27' from sysibm.sysdummy1
)
)
You may need to tweak it to handle some edge cases (I'm not exactly sure if you care what happens if it runs on the 29th of the month, and if so, how to handle it). But you get the basic approach.
You can use DAY() function that extracts day of month from date and you can use it for triggering job. for example where day(param)=28.
other two parameters can be calculated with date calculation , here is example for trigger , date_to value and date_from value
select day(timestamp_format(20170228,'yyyyMMdd') ),timestamp_format(20170228,'yyyyMMdd')- 1 DAY,timestamp_format(20170228,'yyyyMMdd') -1 month from sysibm.sysdummy1;
if your parameter/column is date/timestamp you can remove timestamp_format(20170228,'yyyyMMdd') function and just put your column/parameter

Calculating total working hours based on shifts

I would like to calculate how many hours each employee has worked for a certain time period, based on information from this table:
start employee_id
2014-08-10 18:10:00 5
2014-08-10 13:30:00 7
2014-08-10 09:00:00 7
2014-08-09 23:55:00 4
2014-08-09 16:23:00 12
2014-08-09 03:59:00 9
2014-08-08 20:05:00 7
2014-08-08 13:00:00 8
Each employee replaces another employee and that's where his work is done, so there are no empty slots.
The desired format of the result would be the following:
employee_id total_minutes_worked
I'm trying to think of the best way to achieve this, so any help will be appreciated!
You can get the total time as:
select employee_id, sum(stop - start)
from (
select start, lead(start) over (order by start) as stop, employee_id
from t
) as x
group by employee_id;
It remains to format the time, but I assume this it not what puzzles you
you should use 'GroupBy' clause to first create a group of the same employee id
than you should calculate the time by checking the start time of work and end time of work in each slot.
(NOTE - you should maintain the start time and end time both of the employee in each slot of there shift)

How can I use the PERIOD feature of Temporal Postgres / Postgres 9.2 on Heroku?

I am building an app that deals with times and durations, and intersections between given units of time and start/end times in a database, for example:
Database:
Row # | start - end
Row 1 | 1:00 - 4:00
Row 2 | 3:00 - 6:00
I want to be able to select sums of time between two certain times, or GROUP BY an INTERVAL such that the returned recordset will have one row for each sum during a given interval, something like:
SELECT length( (start, end) ) WHERE (start, end) INTERSECTS (2:00,4:00)
(in this case (start,end) is a PERIOD which is a new data type in Postgres Temporal and pg9.2)
which would return
INTERVAL 3 HOURS
since Row 1 has two hours between 2:00 - 4:00 and Row 2 has one hour during that time.
further, i'd like to be able to:
SELECT "lower bound of start", length( (start, end) ) GROUP BY INTERVAL 1 HOUR
which i would like to return:
1:00 | 1
2:00 | 1
3:00 | 2
4:00 | 2
5:00 | 1
which shows one row for each hour during the given interval and the sum of time at the beginning of that interval
I think that the PERIOD type can be used for this, which is in Postgres Temporal and Postgres 9.2. However, these are not available on Heroku at this time as far as I can tell - So,
How can I enable these sorts of maths on Heroku?
Try running:
heroku addons:add heroku-postgresql:dev --version=9.2
That should give you the 9.2 version which has range types supported. As this is currently very alpha any feedback would be greatly appreciated at dod-feedback#heroku.com

How can I schedule bi-weekly jobs?

My app requires users to schedule recurring events that can recur daily, weekly, monthly, or bi-weekly.
By bi-weekly, I mean every fortnight (14 days) starting from an arbitrary date value provided at the time of creation.
My jobs table has two columns to support this: job_frequency_id and job_frequency_value. I'm able to schedule all types except for bi-weekly.
The first col is an FK to the job_frequencies table; it contains daily, weekly, monthy, bi-weekly values. The job_frequency_value contains the value corresponding to the frequency.
For example: If a job has a job_frquency_id == 3 and job_frequency_value == 10, it will run every 10th day of the month.
How do I add bi-weekly support without tampering with my db structure? I will use the job_frequency_value col to store the start date of the 14 day period, but I'm unsure of the calculation going forward.
Say your starting date is stored as a variable named 'createdDate'.
nextFortnight = DateAdd("ww", job_frequency_value*2, createdDate);
can you wrap your scheduled task in a and set it to run every week?
Something like
<cfif DateDiff('ww',CreateDate(2011,01,01),Today'sDate) MOD 2 EQ 1>
That way if the weeks are odd your scheduled task runs completely and if it's an odd week then it runs the scheduled task, but ignore all your code.