I'm having the schemas like:
Employee (Empno, Empname, City)
Project (Pno, Pname)
Part (Partno, Partname, Color)
Use (Pno, Partno)
Works (Empno, Pno)
From these schemas I had created a sample tables:
The goal is to find the names of the projects where no employees are working whose name starts with 'S'
I'm using ORACLE 11g Express Edition.
Here I used this query :
For Names:
Select DISTINCT Pname FROM
(
SELECT w.Empno, p.Pno, p.Pname, e.Empname
FROM Works w
LEFT JOIN Project p ON w.Pno=p.Pno
LEFT JOIN Employee e ON e.Empno=w.Empno
)
WHERE Empname not like 'S%';
If you think about how to explain the process. There are several methods to solve this including:
You would start with each of the Projects and find out if there does not exist anybody who Works on the project where the Employees name starts with S. You can do this using NOT EXISTS.
or
Again, start with a Project and find, if any, who Works on the project and their corresponding Employees details using LEFT OUTER JOINs (but starting from the Project) and filtering for employee names starting with S in the JOIN condition. Then GROUP BY the primary key for the project and find those projects HAVING a COUNT of zero matched employees.
Since this appears to be a homework question, I'll leave the rest for you to complete.
Related
I'm designing a web form to publish to a SharePoint webpage in Microsoft Access 2010. I have a form that uses a combo box to select a team name. I need to enter the team id corresponding to that team name into the employee table. This is what I have so far:
INSERT INTO Employee ( Employee_Name, Team_ID )
VALUES ([Forms]![Add Employee]![txtName], (SELECT MAX(Team.Team_ID)
FROM Team, Employee
WHERE [Team]![Team_Name]=[Forms]![Add Employee]![cmbxTeam]));
It gives me an error saying
Query input must contain at least one table or query.
How do I fix this?
You can either use the VALUES clause to specify hard coded values, or you can use a SELECT statement to generate the stuff that will be inserted. Here you are combining the two. Instead:
INSERT INTO Employee ( Employee_Name, Team_ID )
SELECT
[Forms]![Add Employee]![txtName],
MAX(Team.Team_ID)
FROM Team, Employee
WHERE [Team]![Team_Name]=[Forms]![Add Employee]![cmbxTeam];
Slightly unrelated, why are you cross joining employees and teams, when you don't need the Employee table in your SELECT?
This should be equivalent and much much faster:
INSERT INTO Employee ( Employee_Name, Team_ID )
SELECT
[Forms]![Add Employee]![txtName],
MAX(Team.Team_ID)
FROM Team
WHERE [Team]![Team_Name] = [Forms]![Add Employee]![cmbxTeam];
These are the tables that I'm working with.
With that in mind, I want to showcase the Employees that are both a supervisor and a manager.
But when I used this
select e1.fname,e1.lname
from employee e1,employee e2,department
where e1.ssn=e2.super_ssn and e1.ssn = Mgr_ssn
This was the output
I know I can solve the problem with 'distinct', but I'm more interested to know why the output turned out like it did.
How about exists?
select e.*
from employee e
where exists (select 1 from employee e2 where e2.mgr_ssn = e.ssn) and
exists (select 1 from employee e2 where e2.super_ssn = e.ssn) ;
Your query returns duplicates for two reasons. First, presumably managers and supervisors have multiple employees below them. You end up with rows for each such employee. Second, you have a cartesian product with department, which further multiplies the rows. The department table is not used in the query.
Using select distinct is not a good solution in this case. The database just ends up having to do a lot more work than necessary -- first to create the duplicate rows and then to remove them.
add department matching clause in where like
select e1.fname,e1.lname
from employee e1,employee e2,department d
where e1.ssn=e2.super_ssn and e1.ssn = Mgr_ssn and
d.Dnumber=e1.Dno
I have two tables on PostgreSQL, namely: employees and employers.
There is data in each of these tables.
Columns in employees: employee_id, employee_name, employer_id.
Columns in employers: employer_id, employer_name.
I want to display all employee_name's that don't have an associating employer_name.
I used the below query:
SELECT DISTINCT a.employee_name, b.employer_name
FROM employees a
NATURAL JOIN employers b
WHERE a.employee_name LIKE 'Jack';
NB!
I have also tried adding in the below to my query:
COALESCE(b.employer_name, '') = ''
Problem:
If there is no record in the employer table containing the associating employee_id value, the query returns nothing all. I am assuming this is because there is nothing for the two tables to join on?... But I would like to at least find all employees that don't have an employer. I would ideally like the employer_name value in my result to either return: blank/''/NULL.
Your assistance is greatly appreciated.
select employees.employee_name ,employers.employer_name
from employees
left join employers
on employees.employee_id = employees.employee_id
where employers.employer_name is NULL
Use a LEFT JOIN:
SELECT a.employee_name,
COALESCE(b.employer_name, 'NA') AS employer_name
FROM employees a
LEFT JOIN employers b
ON a.employer_id = b.employer_id
WHERE b.employer_id IS NULL
Your current query has several problems, first of which is that you are using a NATURAL JOIN, which should behave link an INNER JOIN, discarding employee records which do not match to any employer. Instead, by using LEFT JOIN, we can retain all employee records, regardless of whether or not they have an employer. The WHERE clause checks for NULL in the joined table, with NULL indicating that the employee did not match to any employer.
Your table name employees table is a little odd, IMO. There is a design 'rule of thumb' that says a table models either an entity or the relationship between entities but not both. To demonstrate this oddness, consider the relational operation is
employees MINUS employers
...which suggests something is off.
Another symptom of this design problem is that the employer_id in the employees table must have some kind of placeholder to represent the predicate employee has no employer, possibly a null (and nulls are to be avoided, IMO).
I suggest you fix this design by introducing a third table to model the relationship between an employee and their employer. Herein lies another design problem: shouldn't this new table be named employees? In other words, isn't the very definition of an employee a person who has an employer?
Consider this design instead:
People: person_id, person_name
Employers: employer_id, employer_name
Employees: employer_id, person_id
To find the names of people who are not employees in pseudo-relational notation:
People MINUS Employees { person_name }
SQL is quite a bit more verbose:
SELECT DISTINCT person_name
FROM People
NATURAL JOIN
( SELECT person_id FROM People
EXCEPT
SELECT person_id FROM Employees ) t;
Note your original query needlessly uses range variables a and b. One of the benefits of NATURAL JOIN is the elminiation of duplicate column names. Range variables with NATURAL JOIN always looks odd to me!
I am using the following query:
select P.job_ref, P.emp_num, P.name,
P.job_title , P.job_type,
P.dept_ref, P.dept, J.mgr_rept,
(select P.name as manager_name
from PEOPLE P, JOB J
where J.mgr_rept=P.job_ref)
from PEOPLE P, JOB J
where P.job_ref=J.job_ref
The issue is the manager and employee names reside in the same table under name. job_ref correlates to mgr_rept in the job table. An employees job_ref would equal a value in the job table that would pull up job information. The manager name however lies in the people table. The mgr_rept value would be the managers job_ref number. Using this query returns more than one row so I'm looking for some help please.
Thank you
First of all, you should no longer use the old comma-separated join syntax. It has been replaced in standard SQL with explicit joins more than 20 years ago.
Your subquery selects all people. It is not linked anyway to the record in the main query. Maybe you confused yourself by using the same table aliases again. It should be about this instead:
select
P.job_ref, P.emp_num, P.name,
P.job_title , P.job_type,
P.dept_ref, P.dept, J.mgr_rept,
(
select mgr.name
from PEOPLE mgr
where mgr.job_ref = J.mgr_rept
) as manager_name
from PEOPLE P
join JOB J on P.job_ref = J.job_ref;
I'm not 100% sure however, because I don't understand your table structure completely. This only works if job_ref is unique in table people.
I'm not sure how to word the title correctly, so I apologize if it's confusing.
What I need to do is to count how many projects are run by each department, I need to display each department name and assign a name to the colum with computed results
DEPARTMENT Table Imgur
PROJECT Table Imgur
This is what I have tried so far, but it returns an error:
SELECT DISTINCT DepartmentName, COUNT(*) AS AmountOfProjects
FROM DEPARTMENT, PROJECT;
SELECT DepartmentName, Count(1) AS AmountOfProjects
FROM Project
GROUP BY DepartmentName
You don't need the Department table since the Full Name of the Department is in the projects table.
You left out the Group By. Whenever you have an aggregate function in your select, you need a Group By
When I tried user3083310 solution something still looked wrong, all the Departments were showing 5 projects, and that is wrong. I added the following join and it worked:
SELECT DEPARTMENT.DepartmentName, Count(*) AS AmountOfProjects
FROM PROJECT, DEPARTMENT
WHERE PROJECT.Department = DEPARTMENT.DepartmentName
GROUP BY DEPARTMENT.DepartmentName;
And the output is the following that matches the information the project table.
Department Name: Account Finance Marketing
AmountOfProjects: 1 - 2 - 2