design database model and related sql queries - sql

Develop the rdbms for the administrative structure of an organisation. Each employee belong to a certain dept and is associated with multiple projects. each manager is an employee who manages several projects as well as several employee. Each project executes for a certain duration. employees stay in organisations for a certain duration.
Queries:
find no of employees who has worked is every project
find max no of employees working at a time in project 'x'
find the unproductive managers who manages less than 5 project in last 1 year
find the dept whose employees handled maximum project in last 1 year
edit:
I am not able to decide how to deal with the time constraint in the last 3 queries.
I have made 3 tables:
EMPLOYEE with attributes: emp_id,name,dept,manager_id where emp_id is primary key and manager_id is self referential foreign key
PROJECT with p_id,p_name,manager_id where p_id is primary key
ALLOTMENT with emp_id,p_id where both attributes make a composite primary key
The above helps me answer the first query but how do I add the time constraints to answer the rest of the queries. Do I need date-time attribute or a simple duration attribute will work or something else is required here? please help.

ALLOTMENT is the intersection between EMPLOYEE and PROJECT. It records the employees working on a project.
However, employees join projects and leave projects. Projects grow and shrink in their resourcing. So clearly ALLOTMENT needs columns to indicate the time span of a particular assignment, say START_DATE and END_DATE.
Once you add those columns you will be able to answer the remaining questions. Some of them will remain tricky (especially 2) but at least you will have the information required.
Incidentally, you probably ought to have a DEPARTMENT table but you can write those queries without it. Also, in real life a PROJECT would have an initiation date and (we hope) a completion date. However they too are not required for the queries you have to write.

In the project table consider adding two columns start_date and duration| End_date of the project. I think this will be sufficient for you to work through the last 3 queries.
You can consider having another column No_of_Employees_under_project in project table, which is normalized and will dynamically reflect employees joining or leaving the project. This column should be added only after measuring the gain against the cost of normalization.

Related

How do I filter out records from Table B based on a field in Table A?

Because it may be relevant, the DBMS I am using is Teradata.
I have two tables named Table A and Table B. Table A contains employee personal and company data (company-issued ID, name, pay type, etc.), and Table B
contains information concerning the jobs each employee has held or is currently holding. The primary key for both tables is the employee's company-issued ID number.
Currently, I am trying to write a query that partly entails retrieving an employee's current position.
This seems like it should be easy, especially since Table B stores "effective" dates and "expiration" dates for each job, however, there is a problem.
In the company I work for, there are two different systems used to track employees. Each system is identified by human resources code.
The codes for each system and which employees are included in that system are as follows:
If you work in a retail store in a non-managerial position, your
system is identified by code "1".
If you work in a retail store in a
managerial position or you work for corporate, your system is
identified by code "2".
Each record in Table B has a field indicating which HR system that particular job is tied to.
Occasionally, someone working at a store in a managerial position may need to have a record in the system identified by code "1" in order to have access to
some store-level systems they need to do their work. When this happens, another job record is added to Table B for that employee that is tied to system "1". In such cases, for that particular employee, their two most current records in Table B will correspond
to their actual position within the company while the other will be the additional record created for them. Additionally, these records often have "effective" dates that are later than the "effective" date for the employee's actual job.
In my query, I need to obtain each employee's actual job from Table B. It is known that every genuine system "1" employee is hourly, while everyone in
system "2" is salaried. Table A has a field indicating each employee's current pay type.
So, basically, for each employee included in my query, I need to filter out any cases where an employee has a system "1" record in Table B while Table A indicates that
the employee is salaried and not include them when calculating the employee's actual current position.
I apologize for the "wall of text" here, but I feel this problem is fairly complex, so I wanted to be sure you were aware of all the relevant details.
Admittedly, I am still learning SQL, so if there are any constructs or aggregate functions that can help, please let me know.
Thank you for your time.

Using unique index for cross table constraint

I'm pretty new to Oracle and database design in general but I have a question. I have two basic tables called employee and department. The employee table holds a salary property. Now I need to implement a new business rule: The total of all employee salaries in one department (an employee is part of a department) may not exceed 200k. I know this can be done with a materialized view, but can it also be done with unique indexes? If so, how would one approach this particular situation?
No, you can't use a unique index to enforce this sort of rule.
You could try to enforce this sort of rule via triggers but that tends to get rather difficult in a multiuser environment. You'd need to do things like lock the department row to ensure that only one session can be modifying employee information for a particular department at a time which tends to introduce significant scalability issues. It also tends to involve quite a bit of code to handle all the potential cases.
This can't be done with any indexes. But it is can be done using a trigger.
If you add a column maxDeptSalary to your departments table, then you can create a trigger on Insert and Update in which you
query your maxDeptSalary and get the value
run Sum on existing records in your employee table for that department
compare sum + new.value <= maxDeptSalary
Reject your record if criteria is not met
But the reality is, this is should be done on application level, not the database

Timesheet Database schema

There is an old timesheet application being used in my company and i am going to rewrite it in asp.net.
There are other tables which can be linked to new Timesheet table like employee table but my main concern here is the Project and Project_Activity table.
In the current system, there is a one project and a activity table which are linked to the timesheet table seperatly and user has to spend alot of time on selecting activities code they worked on for specific project.
I have came up with the new idea; Project manager will have to fill up a project template and link all the activities code with the one project before starting this project. This way user will have to select the project only and it will automatically bring the associate codes for them.
Here is the logical schema design.
I like to know if this design will work okay? and is it okay to link Project_Activity table with timesheet?
PROJECT
PK_PROJECT_ID,
NAME
PROJECT_ACTIVITIES
PK_PA_ID,
DESCRIPTION,
FK_ACTIVITY_ID,
FK_PROJECT_ID
ACTIVITIES
PK_ACTIVITY_ID,
DESCRIPTION
TIME_SHEET
PKID,
EMP_ID,
FK_PK_PA_ID,
DATE,
HOURS
PROJECT --> PROJECT_ACTIVITIES <-- ACTIVITIES
|
|
|____TIME_SHEET
Note: Timesheet table has many other fields which are not a part of this question.
I'm assuming an Activity can refer to only one Project?
If so, you don't really need the Project_Activity table, just put the foreign key to the Project table in the Activity table.
If an Activity can refer to more than one Project, then your schema is fine, you have effectively decomposed the many-to-many relationship between Project and Activity. :)
In general the schema is OK. I would not use the naming convention you have, as I find it hard to read. No harm in using full words, but that's an aside.
What I would change is the Timesheet table. Do this instead:
PKID,
EMP_ID,
FK_PK_PA_ID,
STARTDATE,
ENDDATE
This will allow you to easily query who was doing what during a given time more easily. You can also allow records to have a NULL ENDDATE to show an activity currently being worked on.
I would add a trigger to make sure that for the same EMP_ID, a record's STARTDATE and ENDDATE never come between a STARTDATE and ENDDATE of other records (no overlap).

Database design....storing relationship in one table, and the data in another table?

I'm looking at this company's database design, and would like to know the purpose of their design, ie store relationship in one table and the data in another, why do this?
They have this,
EMPLOYEE
Id (PK)
DepartmentId
EMPLOYEE_DATA
EmployeeId (PK)
First Name
Last Name
Position
etc...
Rather than this...
EMPLOYEE
Id (PK)
DepartmentId
First Name
Last Name
Position
etc...
...OR this...(employee can belong to many departments)
EMPLOYEE
Id (PK)
First Name
Last Name
etc...
EMPLOYEE_DEPARTMENT
Id
EmployeeId
DepartmentId
Position
That's a link table, or join table, or cross table.. lots of different names.
How would you assign an employee to two different departments with your design? You can't. You can only assign them to one.
With their design, they can assign the same ID to multiple departments by creating multiple records with the employee ID and different department ID's.
EDIT:
You need to be more specific about what you're asking. Your first question seemed to be asking what the purpose of mapping table was. Then you changed it, then you changed it again.. none of which makes much sense.
It seems now that you are asking what the better design is, which is a totally different question than what you originally asked. Please state specifically what question you want answered so we don't have to guess.
EDIT2:
Upon re-reading, if this is the actual design, then no.. It does not support multiple department id's. Such a design makes little sense, except for one situation. If the original design did not include a department, this would allow them to add a department ID without modifying the original EMPLOYEE_DATA table.
They may not have wanted to update legacy code to support the Employee id, so they added it this way.
Purpose of design is determined by business rules.
Business rules dictate entity (logical model perspective) / table (physical model perspective) design. No design is "bad" if it is built according to the requirements that were determined based on business rules. Those rules can however change over time -- foreseeing such changes and building to accommodate/future-proof the data model can really save time, effort and ultimately money.
The first and third example are the same -- the third example has an extraneous column (EMPLOYEE_DEPARTMENT.id). ORMs don't like composite keys, so a single column is used in place of.
The second example is fine if:
employees will never work for more than one department
there's no need for historical department tracking
Conclusion:
The first/third example is more realistic for the majority of real-world situations, and can be easily customized to provide more value without major impact (re-writing entire table structure). It uses what is most commonly referred to as a many-to-many relationship to allow many employees to relate to many departments.
If an employee can be in more than one department, then you would need a mapping table but I'd do it like the following:
EMPLOYEE
Id (PK)
First Name
Last Name
DEPARTMENT
Id (PK)
Name
EMPLOYEE_DEPARTMENT
EmployeeId_fk (PK)
DepartmentId_fk (PK)
Position
This would allow for multiple positions in multiple departments.
You would do this if an employee can be a member of multiple departments. With the latter table, each employee can only belong to one department.
The only remotely good reason for doing this is to implement an extension model where the master table identifying unique customers does not include all the data for customers that is not always necessary. Instead, you create one core table with the core employee data and and extension table with all the supplementary fields. I've seen people take this approach to avoid creating large tables with many columns that are rarely needed. However, in my experience it's typically premature optimization, and I wouldn't recommend it.
In contrast to many responses, the model included does not support multiple departments per employee - it is not a many to many mapping approach.

Creating Table Relationships

I am working on a VB.net (VS-2010, Win XP Pro 2 SP3), Employee Management Project. I need to keep track of Employee Leave Attendance and also each Equipment assigned to an Employee. How can I achieve this using SQLlite.
It will be very useful if you could provide me with examples as I am completely new to the field of SQL and VB.net
I think this can be done with two tables where one has the primary key while the other has a foreign key, but I am not sure. Also how many tables will I need for storing data in Leave and Equipment Form.
I went through other questions but I was unable to figure out a solution for my problem.
(Sorry, I cannot provide with images as this site prevents me from posting images without 10 reps)
Most problems are only as complex, and as simple as you make them. Out of habbit, nearly all tables end up with a unique ID field. There are exceptions, which I will call "link" tables, eg, ones that provide connection details between two data tables.
Now, in your senario
You would need a "holiday" table, where each row will contain the employee unique ID and either a start/finish date, eg, if they take half a day, it needs to be visible, or, just a year and value, eg in 2011, I booked, 2 lots of 35 hours, and 1 lot of 4 hours eg, Ive taken 2 weeks and half a day.
For the equipment, you would need a data table, since an item can only got to 1 employee, it depends if you're going to use this for booking or not, but if its just like a library, eg I currently have a loaner laptop, then you can just have an employee field in the equipment table. If you need a booking system, then you would require link tables and more complex.
Best way to work out your tables is to try and group your data, and then write the items on peices of paper and see how you as a human do it. After a while you end up able to do so in your head.