SQL Table for Timesheet creation - sql

I'm creating a timesheet using Infopath. The data will be stored in the database, so for that I have to create a table. This timesheet will be used for the whole year.
I need help in creating a SQL table. The table structure I want for this timesheet is:
Project_Category Mon Tue Wed Thu Fri Sat Sun Total
Project 1
Project 2
Project 3
Project 4
Project 5
Other
Total
The days should be with dates (Like, Monday 01/01/2013) or please suggest me if you have a better way to do this.

I would not store this data in a single table. Consider creating this using multiple tables instead of the single table.
For example, you could have a Projects table with ProjectId and ProjectName. Then you could easily link your ProjectId field to a ProjectSummary table which stores ProjectId, DateField and Total. I have no clue what your Total row is suppose to be, but if it's a calculation of a date range, use SQL to calculate those values and do not store that in the table.
Good luck -- there are lots of resources online to get started with SQL -- do a little searching.

As sgeddes has suggested, multiple tables will probably be a much better way to approach this.
Personally I would avoid having more than 1 day per row and also to make it flexible allow more than one entry per day.
The structure I would create is as follows:
Entry_ID INT IDENTITY(1,1) PRIMARY KEY
Timesheet_ID INT,
Project_ID INT,
DateTimeFrom DATETIME,
DateTimeTo DATETIME
This then allows date based calculations to be much simpler.
eg. Number of hours on project X between 20th June and 25th June would be a query like:
SELECT SUM(DATEDIFF(MINUTES,DateTimeFrom,DateTimeTo)/60) AS [HOURS]
FROM MyTable
WHERE DateTimeFrom >= '2012-06-25' AND DateTimeTo <= '2012-06-29'

Related

Relational Database design to store weekly attendance

I need to design a table to store weekly attendance
Format of the form is :
Todays' Date,
Note(if absent for each day)
Monday Y/N
Tuesday Y/N
Wed Y/N
Thurs Y/N
Fri Y/N
How do I design the table to store such information which is recorded on a weekly bases?
Should it be 1 table having columns as
Date , Monday(bit) , MondayNote(varchar) , Tue , TueNote etc upto Fri ?
What is the best approach?
TIA
Instead of storing bits for each day of the week, why not just store the actual date with the flag and note? Something like this:
CREATE TABLE Attendance(AttendanceID int primary key not null identity(1,1), StudentId int not null /* foreign key? */, AttendanceDate date not null, PresenceFlag tinyint not null default(1), Note varchar(max) null);
So instead of using a single date and five flags for days, which would complicate your logic for getting the actual date, store the actual date for each day of the week. This will simplify a lot of query logic.
Note that I am using a tinyint instead of bit. This is to allow you to perform arithmetic operations. SUM(PresenceFlag) will give you total a attendance for a period. You can't do this with bit data type. You can use a CONSTRAINT to ensure only 1 and 0 are allowed.
You can easily get a day of the week from a date using DATENAME(Weekday, AttendanceDate).

SQL Server 2005 simple query to get all dates between two dates

I know there are a lot of solutions to this but I am looking for a simple query to get all the dates between two dates.
I cannot declare variables.
As per the comment above, it's just guesswork without your table structures and further detail. Also, are you using a 3NF database or star schema structures, etc. Is this a transaction system or a data warehouse?
As a general answer, I would recommend creating a Calendar table, that way you can create multiple columns for Working Day, Weekend Day, Business Day, etc. and add a date key value, starting at 1 and incrementing each day.
Your query then is a very simple sub-select or join to the table to do something like
SELECT date FROM Calendar WHERE date BETWEEN <x> AND <y>
How to create a Calender table for 100 years in Sql
There are other options like creating the calendar table using iterations (eg, as a CTE table) and linking to that.
SQL - Create a temp table or CTE of first day of the month and month names

SSAS get active record count between two dates

Can you please let me know the best approach for designing Data ware house and dimension modelling (SSAS cube) based on below requirement.
Requirement here is, I have to get the student count which are active as of that month, if the user selects year (2015) from drop down which is displayed in the image. Catch here there is no option to select enrollstartdate and enrollenddate as two different dates (no role play dimension) , only one filter i.e Year.
Requirement to get the active student count as of that month
There are a couple of possible approaches that come to mind. The first is a periodic snapshot fact table and another is a timespan accumulating snapshot fact table.
In my opinion, the first is easier to implement, so I've provided some detail below that I hope you will find useful.
CREATE TABLE FactEnrollmentSnapshot
(
DateKey INT NOT NULL -- Reference to Date dimension table
, StudentKey INT NOT NULL -- Reference to Student dimension table
);
CREATE TABLE DimStudent
(
StudentKey INT NOT NULL
StudentId ?
...Other Student Attributes...
);
CREATE TABLE DimDate
(
DateKey INT NOT NULL
, FullDate DATETIME NOT NULL
, Year SMALLINT
);
Assuming your date dimension is at the day grain, you could either store daily snapshots, or just store snapshots on the 15th of each month.
Depending on whether you need to get a count of unique students during 2015 or the most recent count of students in 2015 you could use the DISTINCT COUNT aggregation or the LastChild aggregation in SSAS. If you use LastChild, make sure your Date dimension is marked as a Time type.
Note that a snapshot style fact table results in semi-additive facts.
You could get the raw data to populate the fact table from your example source data by using a CROSS JOIN between you source data and the Date dimension
SELECT
StudentTable.StudentID
, DimDate.FullDate
FROM
StudentTable
INNER JOIN DimDate ON (DimDate.FullDate BETWEEN StudentTable.EnrollDate AND ISNULL(StudentTable.DisenrollDate,'9999-12-31'));
I didn't include the lookups for surrogate keys for simplicity
You can then get the answer for your business users be filtering on the Year attribute in the Date dimension.
I hope this is useful in getting you started with a possible approach.
Regards,
Jesse Dyson

Storing datetime or season or quarter in a relational database

I must save an event in a relational database.
This event has a time when it starts.
This will be precisely one of:
a datetime, for example: 05.05.2015 06:00:00
a quarter, for example: 4th quarter of the year 2015
a season, for example: Winter
What would be a good way to store this in a database, so i can distinguish the three types.
Should i create a col for datetype and three other cols for datetime, quarter, season? And what would you use for season and quarter.
Yes, your suggestion makes perfect sense. Create a column for datetype and three other cols for datetime, quarter, season. There are plenty of different ways to do this, here's one approach;
DateType char(1) not null, D = datetime, Q = quarter, S = season
DateTime datetime null
Quarter int null, valid values 1 to 4
Season char(2), valid values Wi, Sp, Su, Au
I would use column constraints to enforce the valid values per column, then a table constraint to enforce the rule that if DateType = D then DateTime must not be null and Quarter and Season must be null etc.
You could skip the Quarter and Season columns and use the DateTime column to store a value to represent quarters 1 to 4 or the seasons but this sort of approach almost always leads to mistakes later on. These values are sometimes called 'magic values' because they aren't what they seem, for example, does 2015-01-01 mean 1st Jan 2015 or 'Quarter 1'? When someone queries your table and forgets to look at the DateType column how will they know? I like to see schemas and data that describe themselves. With my suggestion above (or any similar approach) it would be hard to misinterpret the data in the table.
Saving a few bytes of storage or a few millionths of a second in processing are very rarely worth it - you should design something that will always work all of the time, not something that will work a little quicker, most of the time.

What is the best way to structure Days of the week in a db

This is a normalization thing, but I want I have to hold information about the days of the week. Where the user is going to select each day and put a start time and a finish time. I need this info to be stored in a db. I can simply add 14 fields to the table and it will work (MondayStart,MondayFinish,TuesdayStart, etc). This doesnt seem
Do NOT design your database to match the UI.
My time keeping system at my job has a place to enter data for each day of the week. That doesn't mean you store it that way.
You need a table for users and one for times
User_T
User_ID
Time_log_T
User_ID
Start_dt (datetime)
End_dt (Datetime)
Everything can be derived from this.
If you want to have one check-in per day create a unique constraint on User_ID, TRUNC(start_DT). This will handle third shift that wrap days. RDBMS cannot express that the next start_dt for a given User_ID is > MAX(End_DT) for that user... you'll have to do that in code. Of course if you allow records from previous days to be entered or corrected you'll need to validate them to be non-overlapping in a more complex style.
Think of all the queries you'd throw at these tables; This will beat the 14 columns 99% of the time.
Users
id
...etc...
Days
id
day nvarchar (Monday, Tuesday, etc)
start_time datetime
end_time datetime
user_id
you could also break out day in Days to a day of week to enforce consistency on the day if you only want to allow specific days or what not so Days would become
Days
id
day_of_week_id
...etc...
DaysOfWeek
id
name
I don't think moving the data to another table would accomplish anything. There would still be a one-to-one (main record to 14 fields) relationship. It would be more complex and run slower.
Your instincts are good but in this case I think you would be better off leaving the data in the table. Over-normalization is a bad thing.
You could create a table with 3 columns -- one for the day (this would be the primary key), one for the start time, and one for the finish time.
You would then have one row for each day of the week.
You could extend it with, say, a column for a user id, if you are storing the start and finish time for each user on each day (in this case, the primary key would be user id and day of the week)... or something similar to suit your needs.