DayofWeek, Year & Shiftname - sql

I apologize if my questions seems irrelevant or silly. My expertise on SQL is low.
My questions is that I'm trying to create five columns namely ID, shiftName, DayofWeek, date & year in the database.dbo.tablename. However, I'm not sure and couldn't find the right source to correctly write queries for this.
The logic is a day will have 6 shifts, so the DayofWeek, date and year should correspond to the shift column.
Any help would be appreciated.

This is the most simple table I could think of, that would work in MySQL, SQL Server, PostgreSQL, or DB2:
create table tablename (
id int primary key not null,
shift_name varchar(40) not null,
day_of_week int not null,
"date" date not null
);
I excluded the column year since the column date already includes the day, month, and year.

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).

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.

SQL Table for Timesheet creation

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'

Diff. between dates - SQL plus [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
DateDiff Function
I am trying to find the difference between dates in SQL. The difference in days will have to be displayed when the query is given. I get an error saying that DATEDIFF is an invalid identifier. Any ideas?
Here is the table:-
Create table auctions(
item varchar2(50),
datebought date,
datesold date,
days number
);
Insert into auctions values (‘Radio’,’12-MAY-2001’,’21-MAY-2001’);
Select item,datebought,datesold,DATEDIFF(dd ,datebought,datesold )”days”
from auctions;
The title of the question includes "SQL plus", which implies Oracle to me.
Oracle does not have a DATEDIFF function. The simplest method to determine the number of days between 2 dates using Oracle is to subtract one date from the other.
Select item, datebought, datesold, datesold-datebought as days from auctions;
Oracle stores both date and time info in a date field. It is common practice to store dates truncated to midnight within date fields in Oracle if you don't care about the time.
If your dates are already truncated to midnight, then the computed value will be an integral number.
But if your stored dates include time info, then you may want to truncate the value to get an integral value. I suspect you would want to truncate each date before the subtraction, such that if bought on one day, then any time the next day would count as 1 day. Oracle truncates dates to midnight.
select item, datebought, datesold, trunc(datesold)-trunc(datebought) as days from auctions;
I agree with WarrenT that your table should not have the denormalized days column.
try this,Its working for me
Create table auctions(
item varchar(50),
datebought date,
datesold date,
days int
)
Insert into auctions(item,datebought,datesold)
values ('Radio','12-MAY-2001','21-MAY-2001')
Select item,datebought,datesold,DATEDIFF(dd ,datebought,datesold )as days
from auctions;
In a normalized database design, you would not want to define a table column whose value could be calculated from one or more other columns. You would be better off defining the days held in a SELECT or in a VIEW.
If you were using DB2, you could calculate the days held as DAYS(DATESOLD) - DAYS(DATEBOUGHT)