How to structure reference table changes overtime - sql

This is more of a design issue than technical though I do plan on building my report in PowerBI so any limitations of that system should be noted
I am trying to wrap my head around changes in employee information over time and a time card system.
Let’s say I get a time card report that has some standard information. Thier employee ID, number of hours, task hours charged to, date hours charged and so forth.
I also have a HR report of details of each employee which I of course would link via employee ID. This table would have information like job title, department, name, location and so forth.
I am building a report that would show how many hours are charged each month historically by job title and department.
Let’s say employee 3453 was a Janitor in June and charged 20 hours. In November he became a security Manager and charged 10 hours.
When doing reports in December using the current HR data my report would show that 30 hours were charged to the security department instead of 20 to sanitation and 10 to security.
Adding multiple employee records to the HR table wouldn’t work because it would have duplicate keys
I guess I can’t wrap my head around it.
Any help would be greatly appreciated
Thanks.

This is generally handled by working with a separate table that tracks the details of the employees over time.
For example:
EmpID Position DateStart DateEnd
3453 Janitor 1/1/2018 10/31/2018
3453 Manager 11/1/2018 null
There other ways to handle this. I recommend doing to searching and reading using the term:
"slowly changing dimension"

Related

DAX: Classifying employees based on outcome of measure

I'm trying to classify employees by how many times they've called in sick in a given time period. I already have a measure which calculates the number of times an employee calls in sick in a given context. Below is a rough sketch of what I want the result to look like:
The data set I have has the date of calling in sick as well as the date the employee started working again (given that they have recovered already) for each date that the given employee is employed (so it also shows days that an employee is not sick) example below.
So for the above example I want employee 1 to be classified as "2" if I look at this entire year, however if I drill down to the months I want employee 1 to be classified as "1" in both january and february.
Does anyone know if and how this can be done?
I'm using Visual Studio 2017 SSAS Tabular.
Please tell me if something is not clear :).
I figured out how to do it with the link posted below:
https://www.daxpatterns.com/dynamic-segmentation/

Quarterly Reports on Dates

I have a challenge ahead of me. I have looked at this for a couple of days now in a trial and error sense and am getting tired of not getting it… My SQL knowledge is very very basic.
Each quarter I have to report on the questions below (of course the date period changes):
The number of doctors with whom the designated body has a prescribed connection at 31st December.
The number of doctors due to hold an appraisal meeting in the reporting period (from 1st October to 31st December 2017).
The number of those doctors above who held an appraisal meeting in the reporting period.
The number of those doctors above who did not hold an appraisal meeting in the reporting period.
I have three lists:
A list of staff responsible to the designated body. In a linked table- ‘GMC_Main’ Field- GMC Ref No
A list of all appraisals that have ever taken place (historical and ones performed by staff not responsible to us). In a query called-
‘Latest Appraisal’ Fields- ProfNum, MaxOfAppDate
List of emails in a linked table- ‘MARS_Core’ Fields- ProfNum, EmpSurname, EmpFirstName, EmpEmail
Things to consider
ProfNum and GMC Ref No are the Unique identifiers for each member of
staff.
GMC_Main is the list of all staff that need to be considered in the
report. So should have a row regardless of the results from the other
tables.
All appraisals are valid for 365 days. So The date 1 year in the future from that in MaxofAppDate will be needed to calculate expiry in the period.
Due to software limitations I only have available Access 2016.
I need to count all that should have taken place, including ones that
are still overdue from previous quarters.
Count all the ones that actually took place in the period.
Be able to contact all the ones that did not achieve and appraisal.
At year end (31 March) do this for the entire year and not just the
quarter…
Fuff!
Each time I approach this problem I am missing a group of people or feel I am doing it in a very wrong-handed way.
If anyone could help, then that would be amazing. This is a little beyond me.

How to store availability information in SQL, including recurring items

So I'm developing a database for an agency that manages many relief staff.
Relief workers set their availability for each day in one of three categories (day, evening, night).
We also need to be able to set some part-time relief workers as busy on weekly, biweekly, and in one instance, on a 9-week rotation. Since we're already developing recurring patterns of availability here, we might as well also give the relief workers the option of setting recurring availability days.
We also need to be able to query the database, and determine if an employee is available for a given day.
But here's the gotcha - we need to be able to use change data capture. So I'm not sure if calculating availability is the best option.
My SQL prototype table looks like this:
TABLE Availability Day
employee_id_fk | workday (DATETIME) | day | eve | night (all booleans)| worksite_code_fk (can be null)
I'm really struggling how to wrap my head around recurring events. I could create say, a years worth, of availability days following a pattern in 'x' day cycle. But how far ahead of time do we store information? I can see running into problems when we reach the end of the data set.
I was thinking of storing say, 6 months of information, then adding a server side task that runs monthly to keep the tables updated with 6 months of data, but my intuition is telling me this is a bad fix.
For absolutely flexibility in the future and keeping data from bloating my first thought would be something like
Calendar Dimension Table - Make it for like 100 years or Whatever you Want make it include day of week information etc.
Time Dimension Table - Hour, Minutes, every 15 what ever but only for 24 hour period
Shifts Table - 1 record per shift e.g. Day, Evening, and Night
Specific Availability Table - Relationship to Calendar & Time with Start & Stops recommend 1 record per day so even if they choose a range of 7 days split that to 1 record perday and 1 record per shift.
Recurring Availability Table - for day of week (1-7),Month,WeekOfYear, whatever you can think of. But again I am thinking 1 record per value so if they are available Mondays and Tuesday's that would be 2 rows. and if multiple shifts then it would be multiple rows.
Now and here is the perhaps the weird part, I would put a Available Column on the Specific and Recurring Availability Tables, maybe make it a tiny int and store something like 0 not available, 1 available, 2 maybe available, 3 available with notice.
If you want to take into account Availability with Notice you could add columns for that too such as x # of days. If you want full flexibility maybe that becomes a related table too.
The queries would be complex but you could use a stored procedure or a table valued function to handle it fairly routinely.

How to Query for Due Dates in Access 2007

I have a 2 access 2007 tables with the following fields:
Table 1: Loan Release Table
ReleaseDate as Date
Maturity as Date
MemberName as Text
MemberNo as Text
Term (in months) as Number
Mode (M/Q/Semi-Monthly) as Text
LoanType as Text
LoanAmount as Currency
LoanCode as Text
Table 2: Payments Table
ReceiptNo as Text
DatePaid as Date
MemberName as Text
MemberNo as Text
LoanCode as Text
LoanReceivable as Currency
InterestPaid as Currency
I would like to ask on how to use Query to create a temporary table that will display Members that should pay on current date or a specified date base on their Term, Mode of Payment and Loan Type (Regular Loans every 30 days to pay, Special Loans every 45 days to pay) and their remaining balance.
Here's my First Attempted Query: I tried to subtract 30 days from Current Date and it obviously gave me just the transactions last month. I would like it to list all transactions including those for example Member with Regular Loan 12 month term on their 3rd monthly payment, Member with Special Loan that is due today.
I am thinking of creating another table that contains the schedule of payments of every Loan released and then go from there.
Is there another way than this? Like a Query that can be run everyday without the need for a bulky ScheduleOfPayments table?
I'm an office clerk who 'graduated' from Excel and a novice using Access at worst and I'm not afraid of VBA codes if that is necessary.
If you know of a better way of doing this, please do tell me or point me in the right direction. I'm all for learning new things and having read and learned a lot from stackoverflow before, I am sure that with your help, my question is as good as solved.
Thank you guys for reading my inquiry.
You have here two solutions:
You can write a procedure that will, when needed, calculate\generate a matrix containing payment schedule for each loan and compare it to payment done.
You can write a procedure that will, when a loan is created, generate corresponding records in a payment schedule table. further comparison will be done between the ScheduledPayment table and the Payment table.
So basically you have to manage a similar set of data, either as a calculated/on the fly matrix or as a permanent set of data kept in a table.
The second version is by very very far the most effective one. You think of it as bulky but it is exactly the opposite, and indeed what is done every time you get a loan from a bank, where your banker will let you sign the reimbursement schedule.
The table solution will allow you to make use of all querying facilities, while the calculated solution will force you to write specific procedures each time you'll want to do some data mining. Just think about a question like "What are the expected reimbursements for the month of April 2014?". Answering this question with the ScheduledPayment table will be as easy as getting a cafe out of your nespresso machine. The same answer without the ScheduledPayment table will be like having to do the whole coffee production process before getting your cup ready.

Scheduling Database (Base Schedule + Exceptions)

Currently our employee scheduling for ~800 employees at a 24/7 company is handled with Excel workbooks. I need to move all of the scheduling into an Access employee database I designed that we've been using for years. (NOTE: I know Access isn't the ideal platform for this but it's what I have.)
Each employee has a base schedule such as 2:00am start times with Wed/Thu off. An employee's schedule for any given week will be their base schedule modified by exceptions such as:
Time-Off requests
Shift switching with another employee for a day
Leaves of Absence (basically another form of time off)
Schedule changes based on company needs made by a scheduling administrator
The database needs only store the base schedule and somehow display a given week's schedule. It doesn't need any advanced logic like scheduling based on availability.
I can see a few ways to implement this. The first one that came to my mind was storing the base schedule and then dynamically generating a given week's schedule as needed by combining the base schedule with tables based on the above exceptions (time-off, switches, etc). However, I can't see how to store the base schedule and how to merge the base with the exceptions to generate a schedule. I would think a table like baseSchedule(PKScheduleID, FKEmployeeID, DayOfWeek, StartTime) but I'm not sure.
Another method would be to generate weekly schedules into a table, for example using the "three table Kimball Star" method described here: http://www.damirsystems.com/?p=466. Basically it creates a table full of dates and has a many-to-many relationship with employees to define a schedule. I dislike that method for many reasons such as needing to check/modify that table at the application level every time time-off, etc is added and the need to "generate" a new schedule into the table. Also, it's possible this will swell to 2,000+ employees and I fear poor Access will explode in a ball of flame having a record for every employee for every day.
Does anyone have any design ideas for implementing the base schedule + modifiers method? I'd love to generate schedules on the fly with queries only but I'm comfortable with using VBA if necessary.
Thank You
Edit 8/19/11 4:30pm:
I think I'm going to go with something very similar to bluefeet's answer. Below is the design I mocked up in a blank DB:
Each employee will have a record in the Base table for each day of the week with a start time and the number of hours they're scheduled to work. There's also an Exceptions table listing modifications to the schedule with a date, employee, and his new shift.
For the application level forms and reports I'll pull the base schedule into a recordset with a very sloppy query that outputs something like:
Name Mon Tue Wed Thu Fri Sat Sun
Alice 6:00 PM 6:00 PM Off Off 2:00 PM 2:00 PM 2:00 PM
Bob 4:00 PM 4:00 PM 4:00 PM 4:00 PM Off Off 4:00 PM
Then, in VBA, I'll also pull the exceptions for a date range (a week) into a recordset. I'll loop through the exception recordset, modifying the base recordset (from above) as I go. Then I'll set the form/report to use the modified recordset. It's a bit inelegant but it'll get the job done well enough.
If anyone has any ideas as how to combine the Base and Exceptions tables with output similar to the above using only queries and no VBA please let me know.
Thanks Again
My suggestion would be to have a Base table with the Employee Schedules, then have a table with the exceptions. I have something similar in a Calendar app. I have an Employee table that contains their normal schedules, then I have a separate table that contains the Exceptions - days off, leave early, training, etc.
EmployeeTable
PK - EmployeeID
EmployeeName
Schedule fields - starttime, endtime, days, etc
Employee_ExceptionTable
PK - EmployeeId
ExceptionTypeId
PK - ExceptionStartDate
ExceptionEndDate
ExceptionTypeTable
ExceptionTypeId
ExceptionName - Vacation, Leave Early, Training
Since the Employee_ExceptionTable has a key of EmployeeId and ExceptionStartDate this will only allow one exception per day but these are exceptions to the base schedule. As I said, I have something similar in my application that monitors about 100 people and it seems to work. This might be a starting point for you.
I guess this is one way to do it:
You have 3 tables:
employees (employee_id PK), scheduler (employee_id FK) and timeOff(employee_id FK)
scheduler
date
employee_id (FK of employees table)
start_time
end_time
day_off
comments
Your employees table will have basic employee info.
scheduler table will have schelude data as well as flag for day_off (set 1 if that is the day off) and a comment field for any type for comment.
If the day_off is set to 1 your will have description of day_off in the timeOff table.
timeOff table you can design any way you want. You will have date filed so you know what day it is. You can have reason field where 1 - vacation day, 2 - sick day, 3 - personal day, 4 - switch with another employee and so on. You can have a comment field here as well as employee_id of the person the schedule have been switch with