I am working on a sql query to do the following:
For each project, retrieve the project number, the project name, the number of employees who work on that project.
Here is what I have so far:
select pno, pname,
count(select fname from
employee inner join works_on
on employee.ssn=works_on.essn
inner join project
on works_on.pno=project.pno)
as num_emp from project
Which gives me this error:
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'select fname from employee inner join works_on on employee.ssn=works_on.essn inn' at line 1
Which I am assuming means I can't put a select statement inside a count function, but I do not see how else to do this
Attached is my schema
I'd do it like this, grouping on the project details for which you want the employee count:
SELECT
pno,
pname,
COUNT(employee.snn) AS num_emp
FROM
project
INNER JOIN
works_on
ON works_on.pno = project.pno
INNER JOIN
employee
ON employee.ssn = works_on.essn
GROUP BY
pno,
pname;
EDIT:
Actually, if you want to list projects with no employees assigned then you could make your original query more correct by doing something like:
SELECT
pno,
pname,
(
SELECT
COUNT(fname)
FROM
employee
INNER JOIN
works_on
ON employee.ssn = works_on.essn
WHERE
works_on.pno = project.pno
) AS num_emp
FROM
project;
You don't need the sub query
Count(employee ID) and group by the other fields
You can do it like this:
SELECT pno, pname,count(fname) AS Cnt
FROM employee, works_on, project
WHERE employee.ssn=works_on.essn
AND works_on.pno=project.pno
GROUP BY pno,pname
Use a COUNT(*) with an ordinary join and GROUP BY.
select p.pno, p.pname, COUNT(*) AS num_emp
FROM project AS p
JOIN works_on AS w ON w.pno = p.pno
GROUP BY p.pno
You don't need to join the employee table because you're not using any information from that table -- the information is all in works_on.
If you need to include projects with no employees working on them, you need to use a left join.
select p.pno, p.pname, COUNT(w.pno) AS num_emp
FROM project AS p
LEFT JOIN works_on AS w ON w.pno = p.pno
GROUP BY p.pno
In the unlikely case that there can be multiple entries in works_on for the same project+employee, use COUNT(DISTINCT w.essn) in the queries so they're not counted multiple times.
Related
Hello below is my Code
DB: https://dev.mysql.com/doc/sakila/en/sakila-structure.html
select concat(first_name,' ',last_name) from
customer where customer_id in (
select customer_id from (
select customer_id, count(rental_id) as num
from
category
inner join film_category using(category_id)
inner join film using(film_id)
inner join inventory using(film_id)
inner join rental using (inventory_id)
where name='Sci-Fi'
group by customer_id, rental_id)
where num > 5)T)
when i am executing i am getting the below error
ERROR 1248 (42000) at line 2: Every derived table must have its own alias
Expected Outcome is "full names of customers who have rented sci-fi movies more than 5 times. Arrange these names in the alphabetical order"
Could you please let me know what is the mistake i am doing?
Welcome to SO!
First, it seems like you have 3 opening ( parens and 4 closing ) parens. You should delete the last parenthesis so you have balanced parens.
After that, you want to apply the alias to the deepest level query. (Similar question: What is the error “Every derived table must have its own alias” in MySQL?) You have...
where name='Sci-Fi'
group by customer_id, rental_id)
where num > 5)T)
You probably want...
where name='Sci-Fi'
group by customer_id, rental_id) AS T
where num > 5)
(Don't forget, there is no need for that extra closing paren, so you can see I removed it. It might be part of a bigger query you have, but it doesn't help the standalone code in the question.)
This will stop the immediate error that you're seeing. At least, now on my database, the error I see is: ERROR 1146 (42S02): Table 'db.customer' doesn't exist.
select concat(first_name, ' ', last_name) as Customer_name
from category
inner join film_category
using (category_id)
inner join film
using (film_id)
inner join inventory
using (film_id)
inner join rental
using (inventory_id)
inner join customer
using (customer_id)
where name = 'Sci-Fi'
group by Customer_name
having count(rental_id) > 3
order by Customer_name;
select concat(first_name,' ',last_name) as customer_name from customer
inner join rental
using(customer_id)
inner join inventory
using(inventory_id)
inner join film
using(film_id)
inner join film_category
using(film_id)
inner join category
using(category_id)
where name in ('sci-fi')
group by customer_name
having count(rental_id) > 2
order by customer_name
So im trying to list the department locations, the project names associated with each department and the number of employees that work on each project.
There is a DeptLocations table(Attributes: Dnum, DLoc)
A Project table(Attributes:PName, Pnum, PLoc, DNum)
An Employee table (Attributes: FNAME, M, LNAME, SSN, BDATE, ADDRESS, S, SALARY, SUPERSSN, DNO)
And a Works_On table (Attributes: ESSN, PNO, HOURS).
This is my SQL query:
select DeptLocations.DLocation, Project.PName, count(ESSN)
from Works_On, DeptLocations, Project, Department
where DeptLocations.DLocation = Project.PLocation and Project.PNumber = Works_On.PNo
For some reason it only yields 1 record, when clearly there should be plenty more. Any help would be awesome.
You need to add group by clause - as you've used aggregated function:
select
DeptLocations.DLocation,
Project.PName,
count(ESSN)
from
Works_On
inner join Project on Project.PNumber = Works_On.PNo
inner join DeptLocations on DeptLocations.DLocation = Project.PLocation
group by
DeptLocations.DLocation, Project.PName
Note: It's better to use explicit join instead of comma separated join.
I'm having trouble with creating a view using the Inner Join, i have these 3 tables
Projects (ProjID, ProjName, InitDate, EndDate)
Employees (EmpID, EmpName, Phone, City, Salary)
Assign (ProjID, EmpID, Hours, Status, Date)
What i am triying to do is to create a view with the name "View1" to show me these information:
(ProjID / ProjName / EmpName / Hours) only with the employees who has
a Project ID (ProjID) that begins with "N".
I used this query:
CREATE OR REPLACE VIEW view1 AS
SELECT
projects.ProjID,
projects.ProjName,
employees.EmpName,
assign.Hours
FROM
assign
INNER JOIN employees ON employees.EmpID = assign.EmpID
INNER JOIN projects
WHERE
projects.ProjID LIKE "N%";
The result i got is not working and it shows multiple times the same employee with different Projects ID
you could use this query
select *
from employees
inner join assign on employees.EmpID=assign.EmpID
inner join projects on projects.ProjID=assign.ProjID
where projects.ProjID LIKE "N%";
the difference with your query is that you need to establish the relation between projects and assignments.
Anyway if you have the same employee assigned to more than one project that match the where clause, you will get that employee more than once.
Maybe you should group and use some aggregation formula like sum(hours)
CREATE OR REPLACE VIEW v1 AS
(
SELECT p.ProjID, p.ProjName, e.EmpName, a.Hours
FROM Projects p
INNER JOIN Assign a ON a.ProjID=p.ProjID
INNER JOIN Emplyees e ON e.EmpID = a.EmpID
WHERE p.ProjID LIKE "N%";
);
I would like to remind that if you will SUM(a.Hours)
you will have to group the other projections.
There are two relevant tables: works_on and project. Project contains the following attributes: PName, PNo, PLocation and DNo (department number). Works_on contains the following attributes: SSN, PNo, hours.
I want to only count the SSNs that appear more than twice and then provide the count value, PName and PNo.
This is my attempt so far:
SELECT
P.PNo, P.PName,
COUNT(W.SSN) AS no_employees
FROM
project AS P INNER JOIN works_on AS W ON P.PNO = W.PNo
WHERE W.SSN IN (SELECT SSN FROM WORKS_ON GROUP BY SSN HAVING COUNT(SSN) > 2)
GROUP BY P.PNo
but I get the wrong PNo's and the wrong number of employees. I have been trying to figure out why this code will not give me projects with more than two employees. Please help me figure out what I am doing wrong.
You don't need inner query, group by with having should do, e.g.:
SELECT p.no, p.name, COUNT(w.ssn) as employees
FROM project p JOIN works_on w ON p.pno = w.pno
GROUP BY p.no, p.name
HAVING employees > 2;
I'm trying to execute two separate inner table joins in my query to return values from two tables.
SELECT pname, avg(salary)
FROM project p INNER JOIN department d on p.dnum = d.dnumber
INNER JOIN employee e ON e.dno = d.dnumber;
I'm getting one row in the result set... pname = null, avg(salary) = null.
Result set should contain 11 rows because there are 11 projects in the schema.
Can someone point me in the right direction?
Thank you
You are missing the group by:
SELECT pname, avg(salary)
FROM project p INNER JOIN
department d
on p.dnum = d.dnumber INNER JOIN
employee e
ON e.dno = d.dnumber
GROUP BY pname;
In most databases, your version would fail with an obvious syntax error. MySQL only enforces the ANSI standard if you use the ONLY_FULL_GROUP_BY mode (see here).
Use left outer join instead of inner join
Or can you show me your data tables
Do you need the department table in your query?
Does the following query return all the data you need to summarize?
SELECT pname, salary
FROM ( SELECT salary, dno AS dnum FROM employee ) e
NATURAL JOIN project;
If it does, then this might be the summarization you require:
SELECT pname, AVG( salary ) AS average_salary
FROM ( SELECT salary, dno AS dnum FROM employee ) e
NATURAL JOIN project
GROUP
BY pname;