Normalizing Database Table - database

I was asked an interview question and I want to confirm if I did it right or not. There is a table called Employee saving Employee information alogwith monthly salaries(Assume that this table currently have a year record only)
Employee(ID,Name,Month,Salary)
Sample Data:
ID Name Month Salary
1 A Jan 2500
1 A Feb 3000
2 B Jan 4500
2 B Feb 6500
The question was:
Is this table schema alright? If not how will you resolve it?
I normalized the table and want to know if this is the right way to normalize the above table?
Employee(ID,Name)
tblSalary(ID,Emp_ID,Month,Salary)
Please excuse me if its a very basic question

You've done it right according to:
First Normal Form
Eliminate repeating groups in individual table.
Create a separate table for each set of related data.
Identify each set of related data with a primary key.
Only thing to point out is your "month" entity which i would change to a date instead, as it limits the employee to be employeed for only one year (as pointed out by another comment)

Related

Efficiently store questions exam-wise and also year-wise in Database tables

I am basically trying to solve this problem: "Efficiently find the exam and year in which a question was asked."
For the same year, a question can occur in multiple exams.
For the same exam, a question can occur in multiple years.
An exam occurs each year and only once a year.
An exam can contain multiple questions.
A question may not belong to any exam (for example, it is a self-made question) and in that case it will not belong to any year as well.
There are around 20 entries in Exams table.
Number of entries in Year table till date is around 30 and will increase by 1 for each consecutive year on-wards.
Number of Questions in each exam each year is around 200.
The solution that I can think of so far is following:
Question table:
QuestionId
.
.
around 10-15 more columns
.
.
Exam table:
ExamId
ExamName (like ExamA, ExamB, ExamC)
Year table:
YearId
YearValue (like 1942, 1947, 2013, 2018)
YearwiseExamQuestion table:
YearwiseExamQuestionId
YearId
ExamId
QuestionId
Please suggest if this a good design for a large set of questions?
It sounds like you are designing your database around particular queries you want to derive from your data rather than by the characteristics of the data you are storing. This is problematic if you're trying to save data storage space. If you're not trying to save data storage space, you could go for this.
Your solution will still work, however, it just will take up more space than a more normalized solution. You could save space by making Year Table not a table, but a column in your Exam Table and getting the data by year with a query. If you did that, I think it's still feasible to make Exam Table and Question Table their own tables with foreign key QuestionId in the Exam Table.
Your design looks fine, as in some table you have to maintain the questions corresponding to the exam, YearwiseExamQuestion seems the right table to hold it. Make the YearId,ExamId,QuestionId combination as composite primary key, so that your requirements are satisfied as told in the question. Also, make YearId, ExamId, QuestionId as Primary keys in the respective parent tables. YearWiseExamQuestion is the child table, which holds which question came for which exam on which year.
For the same year, a question can occur in multiple exams.
For the same exam, a question can occur in multiple years.

Storing days of month for one entity in SQL Server

I have an Event table that contains the following columns:
ID
UserId
Title
StartDate
EndDate
Repeat (Check constraint (M,W,D)) -- Monthly, Weekly, Daily
Time
DaysId (FK)
Question 1
I want to add a column for storing many days of month like:
Event 1 has to be repeated monthly in Month days (2, 4, 8, 23)
is it a good idea to store them in one column separated by (, | or etc...)?
is it a good idea to store them in another table as MonthDays (ID, DayNumber)?
Or is there any other way i can accomplish such thing for a fast and efficient way.
Question 2
Events table has a FK column days. which will be not null when the Repeat column value is Weekly. I'm storing days values in another table Days which has the following columns
ID
Mon (bit)
Tue (bit)
Wed (bit)
...
Is there a better way for storing the days?
This will answer your question, but not quite as directly as you would like.
You seem to have an entity eventScheduleRule that defines one rule for an event. This could be on the 3rd of every month. Or the 4th Friday. Or the Sunday after the first full moon of the vernal equinox. Whatever rules you accept, you can have one rule that sets out one or more days for an event.
Then event would seem to contain one or more rules for scheduling the event.
I would suggest following a structure such as this for setting up the scheduling.

SQL hierarchyid on employee table with inactive records (multiple root nodes)

For those using a SQL hierarchyid for an employee table, how do you accomodate inactive (retired, terminated) employee records contained on the same table? In the case of a new CEO (root) this leads to several rows that have a NULL parentID. Is it common practice to migrate those records to a separate table?
We have an employee table that has both active and inactive records. This is useful for many of the downstream systems that use employee data but are slow to update their own related data after an employee leaves. For example, a project system that uses the employee table to track the project manager. If those systems were to refer to a table that only had active employees they would not find matching rows when pulling employee data.
Clarification on question
To clarify the question, I have read articles on multiple roots and I realize that is possible. My question is more about how this is dealt with in the field. As stated, one option is to have inactive records could be moved to a separate table so the root node is always a single CEO. Another option might be a dummy root for "org" followed by all the CEO records (past and present). Or you can skip the "/" root altogether and just start with all the CEO records. I assume this scenario (employee table with active/inactive CEO type records) is common so I wanted to hear what solutions are being used.
Update on source data
FYI - The source employee table is upstream from my system and we get updates from an Active Directory feed. I cannot switch the source to eliminate the child_id / parent_id columns. I can however update our copy to include hierarchyid for the apps downstream from us. I would keep the child_id / parent_id in our data so I could use the feed to update our copy.
One way you can do this and maintain the historical hierarchy is to include a Start & End Date for each relationship. So there are 5 VPs reporting to CEO John, and John is leaving next month. When new CEO Dave come in, these 5 VPs will report to Dave instead. You don't need to change the whole hierarchy.
Another approach is a few fixed title at the top, and simply update the CEO's name from John to Dave (I don't recommend this though but I have seen it being used).

Database Table Referencing Several Records

I'm looking for some guidance as to how to set up a database I am creating. I think the best way to ask the question is to describe the specific scenario:
I have a database that will hold information about student-employees at a school.
I have one table called "Semesters" that contains information about a specific semester (e.g. "Fall/Spring/Summer", year, etc.).
I have another table called "Employees" that contains information about a specific student-employee (e.g. name, jobTitle, startDate, endDate). I would also like to have a reference to the "Semesters" table indicating which semester(s) the employee was hired. So, for example, one column in the "Employees" table would tell me that this specific employee was working during the "Fall2010, Spring2011, and Fall2011" semesters.
The problem is that I don't know how to reference several records in one field.
I am sure that this is a fairly common scenario, I'm just not sure how to go about it.
Answers that reference MS Access or SqlServer would be excellent.
Thanks.
This sounds like a many to many relationship. In such a case you would likely utilize a junction table.
Employees (empID, name)
1 bob
2 moe
3 george
Semesters (semID, name)
1 fall 2010
2 spring 2010
EmploymentHistory (empID & semID)
1 1 (bob was employed fall 2010)
1 2 (bob was employed spring 2010)
2 2 (moe was employed fall 2010)
You can accomplish this with several foreign keys to the Semester table (not Semesters) from the Employee table (not Employees).
If you want to keep track of the semesters that an Employee has worked, I'd normalize that into a WorkHistory table that's one-to-many with Employee and many-to-many with Semester.

Combining data sets without losing observations in SAS

Hye guys,
I know, another post another problem :D :(.
I took a screenshot to easily explain my problem.
http://i39.tinypic.com/rhms0h.jpg
As you can see I want to merge two tables (again), the Base & Analyst table. What I want to achieve is displayed in the right bottom corner table. I’m calculating the number of total analysts and female analysts for each month in the analyst table. In the base table I have different observations for one company (here company Alcoa with ticker AA). When I use the following command:
data want;
merge base analyst;
by month ;
run;
I get the right up corner problem. My observations in the main table are being narrowed down to only 4 observations (for each different year one observation, 2001, 2002, 2005, 2006). What I want is that the observations are not reduced but that for every year the same data is being placed as shown in the right bottom corner. What am I missing in my merge command?
In both tables I have month as a time count variable ( the observations in my base table are monthly) on which I need to merge. For clarity I added 2 screenshots of my real databases in SAS.
The base table:
http://i42.tinypic.com/dr5jky.jpg
The analyst table:
http://i40.tinypic.com/eqpmqq.jpg
Here is what my merged table looks like:
http://i43.tinypic.com/116i62s.jpg
You can clearly see that the merged table only has four observations left for AA (one for each unique year) instead of the original 8.
Anyone an idea to solve this?
Ugh, it appears you can easily solve this by merging on both ticker and month.
Data ftest;
Merge ftest tryf1 ;
By ticker month;
Run;
/shame.

Resources