I have two tables, for example the Employee and Project tables:
Employee (id, dept, joining_date)
Project (emp_id, project)
With Project having foreign key from Employee table.
I have to query on project and dept and return Employee in the order of their joining_date. Which query will work faster on big data set on the queries below?
select * from Employee where id in (select p.emp_id from Project p join Employee e on p.emp_id = e.id where p.project = 'project1' and e.dept = 'dept1') order by joining_date
select * from Employee where id in (select p.emp_id from Project p join Employee e on p.emp_id = e.id where p.project = 'project1' and e.dept = 'dept1') and dept = 'dept1' order by joining_date
Or is there any better and simpler way to do so?
The outer query using the IN() expression serves no purpose is entirely unnecessary. This will produce the output you need:
select e.*
from Project p
inner join Employee e on p.emp_id = e.id
where p.project = 'project1' and e.dept = 'dept1'
order by joining_date
Related
Im going over a past paper and have found some select statements I cannot do. Can anyone help with these? I'm using MySQL. Thanks
Schema:
employee = (employee id, name, address, date of birth, salary)
project = (project id, name, budget, start date, end date)
manages = (employee id, project id)
works on = (employee id, project id)
Questions :
Names and addresses of all employees who work on projects which are
current (have not ended yet)
The names of managers of projects, ordered by the total number of employees they manage
The names of employees who work on the project with the largest budget
amount.
My attempts:
1.
select employee.name, address
from employee natural join works_on natural join project
where end_date is null
2.
select employee.name, count(works_on.employee_id) as manages_count
from (employee natural join manages) joins works_on using (employee_id)
I'm completely lost I cannot even attempt this one ^
3.
select employee.name, address, budget
from employee natural join works_on natural join project
order by budget
limit n
^ I know this is wrong as technically I should be able to show them without a limit
Here you go:
1.
select
e.name,
e.address
from employee e
join works_on w on w.employee_id = r.employee_id
join project p on p.project_id = e.project_id
where p.end_date is null
2.
select
n.name
from employee n
join manages m on m.employee_id = n.employee_id
join works_on w on e.project_id = m.project_id
group by n.employee_id
order by count(*) desc
3.
select
e.name
from employee e
join works_on w on w.employee_id = e.employee_id
join project p on p.project_id = w.employee_id
where p.project_id in (
select project_id from project where budget = (
select max(budget) from project
)
)
So i have an employees table:
I'm trying to create a query that displays all the info of this employee but i'm a little stumped at the Employee_Reports_To bit. What i want to appear is the First_Name and Last_Name of the Employee_ID that's stored in this column (Eg Joe Bloggs ID 1, reports to employee Joanne Blog ID 50)
Would this need a join or just a simple select. The database is having issues with the link when i try..
SELECT employee.*, departments.Department_Name,
jobTitle.Job_Title,
(SELECT manager.First_Name, manager.Last_Name
FROM Employee manager
INNER JOIN employee AS employeeReportsTo
ON manager.Employee_Reports_To = manager.Employee_ID
) AS Reports_To
FROM Employee employee
LEFT JOIN Departments AS departments
ON departments.Departments_ID = employee.Departments_ID
LEFT JOIN Job_Title AS jobTitle
ON jobTitle.Job_Title_ID = employee.Job_Title_ID
ORDER BY `employee`.`Record_Active` DESC,
`employee`.`First_Name` ASC
Any assistance would be appreciated!
Try this solution:
SELECT emp.*,
manager.First_Name,
manager.Last_Name,
departments.Department_Name,
jobTitle.Job_Title
FROM Employee emp
INNER JOIN Employee manager
ON emp.Employee_Reports_To = manager.Employee_ID
LEFT JOIN Departments AS departments
ON departments.Departments_ID = emp.Departments_ID
LEFT JOIN Job_Title AS jobTitle
ON jobTitle.Job_Title_ID = emp.Job_Title_ID
ORDER BY emp.Record_Active DESC,
emp.First_Name ASC
It's always better to use Join instead of using Sub Query.
EDITED:
Since column Employee_Reports_To can be null so it's better to use LEFT JOIN instead of INNER JOIN. Like This:
SELECT emp.*,
manager.First_Name,
manager.Last_Name,
departments.Department_Name,
jobTitle.Job_Title
FROM Employee emp
LEFT JOIN Employee manager --Changed Join here
ON emp.Employee_Reports_To = manager.Employee_ID
LEFT JOIN Departments AS departments
ON departments.Departments_ID = emp.Departments_ID
LEFT JOIN Job_Title AS jobTitle
ON jobTitle.Job_Title_ID = emp.Job_Title_ID
ORDER BY emp.Record_Active DESC,
emp.First_Name ASC
Looking to your code you could use two time Employee (with alias e1 and e2) one for employee and one for the related manager
SELECT e1.*
, departments.Department_Name
, jobTitle.Job_Title
, e2.First_Name
,e2.Last_Name
FROM Employee e1
INNER JOIN Employee e2 ON e1.Employee_Reports_To = e2.Employee_ID
LEFT JOIN Departments AS departments
ON departments.Departments_ID = e1.Departments_ID
LEFT JOIN Job_Title AS jobTitle
ON jobTitle.Job_Title_ID = e1.Job_Title_ID
ORDER BY e1.`Record_Active` DESC,
e1.`First_Name` ASC
I am working on a sql query to do the following:
For each project, retrieve the project number, the project name, and the number of employees from department 5 who work on the project.
So far my query looks like this:
SELECT p.PNO
, p.PNAME
, COUNT( DISTINCT w.ESSN) '# employees from Dept. 5'
FROM project p
JOIN department d
ON d.DNO = p.DNO
JOIN employee e
ON e.DNO = d.DNO
JOIN works_on w
ON w.ESSN = e.SSN
WHERE e.DNO LIKE '5'
AND p.PNO LIKE 10
Where I am testing it for project number 10 which should return the number of employees from Dept. 5 as 1, however it returns NULL. I think that I need to somehow join the project and employee tables but I am unsure
Attached is my schema
ER Diagram
Your joins are wrong.
You should be joining only projects, works_on and employee tables.
SELECT p.PNO, p.PNAME, COUNT( DISTINCT w.ESSN) '# employees from Dept. 5'
FROM project p
INNER JOIN works_on w
ON p.pno = w.pno
INNER JOIN employee e
ON w.essn = e.essn
WHERE e.DNO LIKE '5' AND p.PNO LIKE 10
And you are missing the group by at the end:
GROUP BY p.PNO, p.PNAME
How do I get the amount of income each employee automatically, based on how the number of employees who participated in the construction project .
Already tried this , but the error . Subquery returned more than 1 row .
SELECT e.name,
( SELECT( p.costs / count(r.employee_id))
FROM relation_employee r GROUP BY r.project_id ) AS revenue
FROM project p
INNER JOIN relation_employee r ON p.id = r.project_id
INNER JOIN employee e ON r.employee_id = e.id
table employee
id INT
name VARCHAR
table project
id INT
name VARCHAR
costs INT
table relation_employee
employee_id INT
project_id INT
Instead of using a correlated subquery in the select part you could get the employee count per project as a derived table to use in the from part, which at least to me looks a bit cleaner. The query could look like this:
-- revenue per employee
SELECT e.name, sum(p.costs * 1.0 / emp_count) AS revenue
FROM project p
INNER JOIN relation_employee r ON p.id = r.project_id
INNER JOIN (SELECT project_id, count(employee_id) emp_count FROM relation_employee GROUP BY project_id) c ON c.project_id = p.id
INNER JOIN employee e ON r.employee_id = e.id
GROUP BY e.name;
-- revenue per employee and project
SELECT
e.name as employee_name,
p.name as project_name,
sum(p.costs / emp_count) AS revenue
FROM project p
INNER JOIN relation_employee r ON p.id = r.project_id
INNER JOIN (SELECT project_id, count(employee_id) emp_count FROM relation_employee GROUP BY project_id) c ON c.project_id = p.id
INNER JOIN employee e ON r.employee_id = e.id
GROUP BY e.name, p.name;
Sample SQL Fiddle
I have the folowing tables.
ORDER
OrderNumber
CustomerNumber
EmployeeNumber
OrderDate
CUSTOMER
CustomerNumber
Name
Address
EMPLOYEE
EmployeeNumber
Name
Address
ORDERDETAIL
OrderNumber
Qty
Description
Price
Let say ORDERDETAIL table has 10 records
I would like to write a query that will return 10 records from ORDERDETAIL table to include Employee name, employee address, customer name, customer address and and order Date.
I know that I could write a query and use INNER JOIN to get the info from ORDER table, but how do you create the rest of query to get the info from the CUSTOMER and EMPLOYEE tables.
SELECT *
FROM OrderDetail D
INNER JOIN Order O
ON D.OrderNumber = O.OrderNumber;
Just add some more joins...
SELECT *
FROM OrderDetail D
JOIN Order USING (OrderNumber)
JOIN Customer USING (CustomerNumber)
JOIN Employee USING (EmployeeNumber)
You might want to re-order the JOINs in order to have the smallest tables first, as this could provide you with some performance boost (depending on your server's version, the most recent will optimize the join for you and might actually execute the joins in the "probably best" way).
Also, in the MySQL dialect at least, JOIN implicitly expands to INNER JOIN, and writing
A JOIN B USING (COL)
is equivalent to writing
A JOIN B ON (A.COL = B.COL)
SELECT *
FROM OrderDetail D
INNER JOIN Order O ON D.OrderNumber = O.OrderNumber
INNER JOIN Eployee E on O.EployeeNumber = E.EployeeNumber
INNER JOIN Customer C on O.CustomerNumber = C.CustomerNumber
if you have foreign key reference between
ORDER.EmployeeNumber and EMPLOYEE.EmployeeNumber
ORDER.CustomerNumber and CUSTOMER.CustomerNumber
then try this
SELECT
E.name AS employeeName,
E.Address AS employeeAddress,
C.name AS customerName,
C.Address AS customerAddress.
O.OrderDate
FROM OrderDetail D
INNER JOIN Order O ON D.OrderNumber = O.OrderNumber
INNER JOIN EMPLOYEE E ON E.EmployeeNumber = 0.EmployeeNumber
INNER JOIN CUSTOMER C ON C.CustomerNumber= 0.CustomerNumber
LIMIT 0,10