How to add multiple employees to a Product - sql

I am very NEW to SQL and know few things here and there.
I am puzzled with this for a couple of days and can't find an answer for it. What I am trying to do is to assign multiple people to a project in way that their name would appear based on their Job Assignments.
For example:
I have table called Products and in that table I have:
Model_ID -> This is set to Primary Key
Model_Name,
PM,
Designer
I have another table called Employee and in that table I have:
Employee_ID -> This is set to Primary Key
First_Name,
Last_Name,
email,
Job_Title
Under Job_Title, for each Employee, I would have their position in the company like PM, Designer, AE, Server PM, etc.
What I am trying to do is to list a corresponding Employee name under a Products table PM column if person is assigned as a PM and under Designer column if person is assigned as a Designer for that product. I have included screenshot of my diagram...
I understand I don't have them linked because everything I tried so far, I couldn't make it work. I am just trying to illustrate what I'm trying to do.
Any help/ pointers would be greatly appreciated and I am open to create new tables if needed (like separate job functions out of Employee table into a separate table, etc.)
The end result should look like:

If I'm understanding your question correctly, the following should do the trick:
Select p.Product_ID, p.Model_Name, e1.First_Name as PM, e2.First_Name as Designer
from Product p
left join Employee e1 on e1.Employee_ID = p.PM
left join Employee e2 on e2.Employee_ID = p.Designer
If you want to use full names, then:
Select p.Product_ID, p.Model_Name, e1.First_Name + ' ' + e1.Last_Name as PM, e2.First_Name + ' ' + e2.Last_Name as Dessigner
from ...
I used Left Joins in case not every product has both a PM and Designer assigned yet. You should probably have two foreign key relationships on your project table though, one for PM and one for Designer, and both will use the Employee table's Employee_ID as the key.
Design View
If you want to do this in Design View, I think you will need to add a second copy of the Employee table and 'link' the PM field to Employee_ID in one Employee table and the Designer field to Employee_ID in the other.
I hope this helps.

Related

Populate SQL query with blank rows

(This is a general SQL question, but I am specifically using MSAccess 2010 so looking for how to do this with Access' flavor of SQL)
I have a table called offices which has id, office_name, num_desks.
Another table called employees which has id, employee_name.
And a final table called employee_offices which has id, office_id, employee_id.
I can assign employees to offices via employee_offices.
I am trying to generate a report which shows all offices and the employees assigned to the, but also includes blank lines for any empty desks in that office.
I realize a "simple" way to do this would be to create a desks table with id, office_id, delete the num_desks column from the offices table and change employee_offices to something like employee_desks. Then my report would be a simple LEFT OUTER JOIN and it would include all the unassigned desks. However for the sake of sanity (in this case, there is no contextual difference between desks), I am not going to do this. Plus if I start deleting desks I have referential constraints to deal with (which obviously exist for a good reason and would catch the fact that I am leaving employees without a desk), but I just want to be able to change the number of desks.
I can calculate the number of empty desks (or lack of desks) through the following command:
SELECT
office_id,
num_desks - num_employees AS desk_diff,
MAX(0, num_desks - num_employees) AS blank_rows_to_add
FROM offices LEFT OUTER JOIN (
SELECT office_id, COUNT(employee_id) AS num_employees
FROM employee_offices
GROUP BY office_Id
) AS num_employees_by_office ON offices.id = num_employees_by_office.office_id
Is there a way to take this number (blank_rows_to_add) and somehow utilze it to add that many blank rows (or at least the row only has the office_id/office_name) to a report showing a list of employees by office? I know this can be done with VBA but I am specifically looking for an SQL method that also doesn't include a temp table if at all possible.
Thank you.

SQL Query Involving Data From Different Tables

I have two different tables with records I need to join together in a way I can't quite figure out how to make work. My data looks like this.
Table A
Columns: Employee_ID, Employee_Department, Employee_Team, Manager_ID, Is_a_Manager ... many other columns
Sample Values:
12345 Department1 Team1 67890 Yes/No
.
.
.
One employee per row, several thousand rows comprising the entire company
Table B
Employee_ID, Manager_ID ... other columns
The exact same data set as Table A
Currently I'm combining those two tables (and three others) with a simple join on Employee_ID, which I'm then using as a data source in Tableau to visualize the data.
What I'd like to do with a SQL script is as follows:
Check to see whether an employee in Table A is a manager or not based on the Is_a_Manager column
If they are, find an employee in Table B who is one of their direct reports by matching the employee ID in Table A to the Manager ID in Table B.
Lookup that direct report's department and team in Table A by matching the Employee_ID in Table B to Employee_ID in Table A and displaying the Employee_Department and Employee_Team columns.
Add the direct report's department and team to two new columns in the original manager's Table A row
I'd like the final output in Table A to be something like
Employee_ID, Employee_Department, Employee_Team, Manager_ID, Is_a_Manager? ... Direct_Report_Department, Direct_Report_Team
Also, an important point is that some managers will have employees who are on different teams, so values in the Direct_Report_Department and Direct_Report_Team are not distinct. I only actually need any one employee's Department and Team to display, it doesn't matter which employee's it is.
Finally, I am able to do step 1 fairly easily in Tableau, so if the SQL script could do steps 2-4 and simply return a null value if the employee was not a manager, that would work for me as well.
Any ideas on how to accomplish this would be greatly appreciated. Thank you!
This should work based on the requirement provided. You don’t have to do any of the steps in Tableau and can simply export the output from the SQL as your data source
Select Tb1.Employee_ID, Tb1.Employee_Department, Tb1.Employee_Team, Tb1.Manager_ID, Tb1.Is_a_Manager, Tb3. Direct_Report_Department, Tb3. Direct_Report_Team
from Table_A Tb1
join (Select Manager_id, max(Employee_id) as emp_id from Table_B group by Manager_id) Tb2
on Tb1.Employee_id = Tb2.Manager_id
left join (Select Employee_ID, Employee_Department as Direct_Report_Department, Employee_Team as Direct_Report_Team from Table_A group by Employee_ID, Employee_Department, Employee_Team) Tb3
on Tb2.emp_id = Tb3.Employee_ID
where Tb1.Is_a_Manager = 'Yes';

How to query in a way that relates a name to an ID and then using that ID to sum up what comes under that ID

I'm a student learning SQL. With querying, if you are given data that you have to relate to a primary key in the same table that will then be used to identify data in another table, how do you query that? I only want a push in the right direction because I don't want to copy and paste someone's code.
For example:
You are to find out how many staff are being managed by a manager and you are to find this by using the managers first and last name (which is not the primary key). The database is below. ManagerNo and StaffID are the same.
Branch (BranchNo, ManagerNo)
Staff (staffID, fName, lName, position, BranchNo)
Thank you for your time
You would use two joins:
select s.*
from staff s join
branch b
on s.BranchNo = b.BranchNo join
staff sm
on sm.staffId = b.ManagerNo
where sm.fname = ? and sm.lname = ?;

I am trying to write a SQL Server query using joins and having some difficulty

Tables are explained in detail as below:
I have 3 tables:
Table A:
It serves as the master table for information about the employees.
EmployeeId(Primary key)
Employee Designation
EmployeeName (More columns of employee data which is not relevant to this particular query)
Table B:
It serves as table where all employees who are accounted for are stored. For ex an employee who has reported sick or is on leave or has pregnancy leave, etc. Bottom line an employee which is not available
EmployeeID (primary key) (also referencing master table A as foreign key)
AccountedFor
AccountedFordurationFrom (datetime)
AccountedForDurationTo (datetime)
Table C:
It serves as a table where excused data of employees are present. For ex we have our organization's time table spread as events, 1st event is morning time conference, then 2nd is silence working time, 3rd is brainstorming sessions etc. Now if an employee is excused for a particular event, it is entered here.
EmployeeID
EventCode
Excuse_DurationFrom
Excuse Duration To
Any specific details
Here EmployeeID and ExcusedForEventCode are both composite primary keys as it is possible to have same employeeId for multiple excuses,but the combination is always unique.
We have built some custom attendance management system and would require the following details:
We need to find all those employees who are neither accounted for nor excused for a specific event(this will be provided through front end) for a time duration selected through the front end.
The result of the above query will subsequently be used to compare with a biometric attendance machine logs which gives
EmployeeId|LogDate(datetime)|EventCodes as a separate table input to our database (Master table A employeeId references this EmployeeId as foreign key)
It will be compared to find out true absentees for a particular event. ie All those employees who are neither accounted for, nor excuses for any particular event and who does not figure out in the biometric scan machine logs are absented for those time duration selected. We need the output of absentee like this EmployeeId|Employee Designation|Employee Name|EventName (have a separate table linking with EventCode)|Date&time (this would be per day per event report of employee who are absent from the selected time duration).
We have tried queries like:
select
employeemastertable.employeeid,
employeemastertable.Designation,
employeemastertable.Name,
EventCodes.EventCodeName as Eventexcusedfrom
from
employeemastertable
inner join
employeeexcusedforevents on employeemastertable.employeeid = employeeexcusedforevents.employeeid
inner join
EventCodes on employeeexcusedforEvents.ExcusedForEventCode = EventCodes.Eventcode
left join
employeeaccountedFor on employeemastertable.employeeid = employeeaccountedFor.employeeid
where
employeeexcusedforevents.ExcusedForEventCode != 1 (Morning conference)
and employeeaccountedFor.employeeid is null;
Names have been changed
I do understand this will give those employees who does not figure out in event Morning conference but even if I do left join instead of inner join between employeemastertable and employeeexcusedForevents and put employeeexcusedforevents.excusedforeventcode is null and employeeexcusedforevents.employeeid is null, I do get all those employees not present in the other two table, but the criteria of event is not satisfied. That means what if the employee is excused for the 2nd event as well in the organization. How would I cater for that in the above code? (PS this is only the 1st part of the equation I understand that, after this I need help for the other part also, where time duration and comparing with logs is concerned)?
I assume there will be just one row for the EventCode=1 in table EventCodes. Below I cross join the wanted event to the employee master table and then exclude any employees that are excused or accounted for.
-- employees neither accounted for nor excused for a specific event
SELECT
em.employeeid
, em.Designation
, em.Name
, ec.EventCodeName AS Eventexcusedfrom
FROM employeemastertable em
CROSS JOIN (
SELECT Eventcode, EventCodeName
FROM EventCodes
WHERE Eventcode = 1
) ec
WHERE NOT EXISTS (
SELECT NULL
FROM employeeexcusedforevents ee
WHERE em.employeeid = ee.employeeid
AND ec.Eventcode = ee.ExcusedForEventCode
)
AND NOT EXISTS (
SELECT NULL
FROM employeeaccountedFor eaf
WHERE em.employeeid = eaf.employeeid
)
;

sql: how to query foreign key not based upon ID

My table IncomingLetter has a foreign key to a table Department, which has an ID and a column Short_Name.
I'm using this query to count the incoming letters assigned to a department.
SELECT COUNT(DocumentNumber) AS TotalNumberIncomingLetters
FROM IncomingLetter
WHERE Assigned_To_Department=1;
Whereas this works I want to make a query based upon the short name and not based upon the ID.
SELECT COUNT(DocumentNumber) AS TotalNumberIncomingLetters
FROM IncomingLetter
WHERE Assigned_To_Department.Short_Name="My Department Name";
This does not work, whereas I found examples that are using this syntax. However, it is probably important to notice, that I m using this query in MS access.
You should use
SELECT COUNT(il.DocumentNumber) AS TotalNumberIncomingLetters
FROM IncomingLetter il
INNER JOIN Department d on d.ID = il.Assigned_To_Department
WHERE d.Short_Name="My Department Name";
The "My Department Name" text is actually stored in the Departments table, and only the number (1) is stored in the IncomingLetter table, in the field Assigned_To_Department.
Asking for Assigned_To_Department.Short_Name basically asks the number 1 to get it's Short_Name field, that does not make sense.
You need to tell the database engine two things in these scenarios:
which tables are connected - IncomingLetter and Departments in this case (the inner join part)
how they are connected - by setting their Assigned_To_Department and ID fields respecively (the on ... part