Having trouble combining two queries (subquery) - mysql

So I want to make a query that shows the managers name who have employees with less than two orders. I have two queries:
This one shows employees who have less than two orders
Select Employee.EID
FROM Employee, OrderT
WHERE Employee.EID = OrderT.EID
GROUP BY Employee.EID
HAVING COUNT(OrderID) < 2
This one shows the manager of each employee
SELECT Employee.Name AS Manager
FROM Employee, Employee M
WHERE Employee.EID = M.ManagerID
GROUP BY Employee.Name
I am trying to combine them and make a subquery but for the life of me I can't figure it out. I keep trying different things for the past two hours and can't seem to get it. Any ideas?

Just need to add manager id to first query since the manager field is in the employee table.
Select Employee.EID, Employee.ManagerID
FROM Employee, OrderT
WHERE Employee.EID = OrderT.EID
GROUP BY Employee.EID
HAVING COUNT(OrderID) < 2

Related

Trying to get a row count in a subquery

I have two tables, one is departments and the other is employees. The department id is a foreign key in the employees table. The employee table has a name and a flag saying if the person is part-time. I can have zero or more employees in a department. I'm trying to figure out out to get a list of all departments where a department has at least one employee and if it does have at least one employee, that all the employees are part time. I think this has to be some kind of subquery to get this. Here's what I have so far:
SELECT dept.name
,dept.id
,employee.deptid
,count(employee.is_parttime)
FROM employee
,dept
WHERE dept.id = employee.deptid
AND employee.is_parttime = 1
GROUP BY employee.is_parttime
I would really appreciate any help at this point.
You must join (properly) the tables and group by department with a condition in the HAVING clause:
select d.name, d.id, count(e.id) total
from dept d inner join employee e
on d.id = e.deptid
group by d.name, d.id
having total = sum(e.is_parttime)
The inner join returns only departments with at least 1 employee.
The column is_parttime (I guess) is a flag with values 0 or 1 so by summing it the result is the number of employees that are part time in the department and this number is compared to the total number of employees of the department.
As a preliminary aside, I recommend expressing joins with the JOIN keyword, and segregating join conditions from filter conditions. Doing so would make the original query look like so:
select dept.name, dept.id, employee.deptid, count(employee.is_parttime)
from employee
join dept on dept.id = employee.deptid
where employee.is_parttime = 1
group by employee.is_parttime
It doesn't make much practical difference for inner joins, but it does make the structure of the data and the logic of the query a bit clearer. On the other hand, it does make a difference for outer joins, and there is value in consistency.
As for the actual question, yes, one can rewrite the original query using a subquery or an inline view to produce the requested result. (An "inline view" is technically what one should call an embedded query used as a table in the FROM clause, but some people lump these in with subqueries.)
Example using a subquery
select dept.name, dept.id
from dept
where dept.id in (
select deptid
from employee
group by deptid
having count(*) == sum(is_parttime)
)
Example using an inline view
select dept.name, dept.id
from dept
join (
select deptid
from employee
group by deptid
having count(*) == sum(is_parttime)
) pt_dept
on dept.id = pt_dept.deptid
In each case, the subquery / inline view does most of the work. It aggregates employees by department, then filters the groups (HAVING clause) to select only those in which the part-time employee count is the same as the total count. Naturally, departments without any employees will not be represented. If a list of department IDs would suffice for a list of departments, then that's actually all you need. To get the department names too, however, you need to combine that with data from the dept table, as demonstrated in the two example queries.

SQL Complex Query w/ Inner Join

I have 2 tables, 1 called Employee and 1 called Salary. Employee table consists of Emp_Name, Emp_Address, Emp_ID & Salary table consists of Salary_Details and Emp_ID. > Can you write down a query for retrieving the Salary_Details of 1 of the employee based on last name using Inner Join?
I am not sure what you are looking for, but this might help you:
SELECT * FROM Employee e
INNER JOIN Salary s ON e.Emp_ID = s.Emp_ID
WHERE e.Emp_Name = 'EMPLOYEENAME'
That will give you back all fields from Employee and Salary for an Employee with the name = 'EMPLOYEENAME' (which you can exchange then).
You can adjust the columns returned as needed depending on your app...
SELECT e.Emp_Name, e.Emp_ID, s.Salary_Details
FROM Employee e
INNER JOIN Salary s USING (Emp_ID)
WHERE e.Emp_Name = 'Smith';
The USING keyword is kind of obscure and works only if the join column is named identically in both tables. The previous answer with ON instead of USING will work in all cases. I like USING as a personal preference.

Alternative way to have an SQL query of Group By

I have two tables with columns:
Table: Employee
1.empName
2.empNo
3.deptId
Table: Department
1.deptId
2.deptName
I have written a query-
select count(*) as total, d.deptName, e.empName from Employee e JOIN Department d on e.deptid = d.deptid
Group By d.deptName, e.empName;
The above query works fine, but I wanted to learn How can I write a query to avoid including a e.empName in Group By clause, and still select it?
Is there any alternative way to accomplish this.
IF you are grouping something then you need to specify aggregate for all columns . If you are not doing so then it must be in group by for those columns.
In your case if you want to achieve it than you have to specify any aggregate function to e.empName column.
You could take the min or max of the name but this assumes that you only have one employee per department.
select count(*) as total, d.deptName, MIN(e.empName) from Employee e JOIN Department d on e.deptid = d.deptid
Group By d.deptName;
Basically if you're grouping by department you'll only get one row per department so if you've got several rows of employees per department you can't include it without some sort of transition, be careful with this, it could lead to some strange and dangerous results.

MySQL - Group By SUM with two tables

I'm using MySQL 5.1 and I have two tables, projects and employee. There is a foreign key in employee (number_project) that is the primary key of projects(code_project).
---> Exactly: SQL Fiddle
I'm trying get the SUM of the projects by department with this query:
SELECT emp.department_emp AS Department, SUM( pro.price ) AS total_department
FROM employee AS emp, projects AS pro
WHERE emp.number_project = pro.code_project
GROUP BY emp.department_emp
It returns:
DEPARTMENT TOTAL_DEPARTMENTA
Accounting 2600
IT 4200
But It should returns:
DEPARTMENT TOTAL_DEPARTMENT
Accounting 1300
IT 4200
The problem is that when the query sums the same projects many times as employees of the same department are working in that project.
Thanks!
Use a subquery to create a list of unique (department, project) combinations:
select e.department_emp
, sum(p.price)
from (
select distinct department_emp
, number_project
from Employee
) e
join Projects p
on p.code_project = e.number_project
group by
e.department_emp
Working example at SQL Fiddle.
Your database could use some serious work. Employee to project should be a many-to-many relation, not a many-to-one relation. And a field called "number" should not be called "code" in another table.
You can use a subquery that "collapses" the employees, arbitrarily choosing the department of one employee from the project:
SELECT department,
SUM(price) AS total_department
FROM ( SELECT project.code_project AS project,
project.price AS price,
MIN(employee.department_emp) AS department
FROM project
JOIN employee
ON project.code_project = employee.number_project
GROUP
BY project.code_project,
project.price
)
GROUP
BY department
;
(Naturally, this will give misleading results if a single project has employees from multiple different departments, because it will assign the entire price of the project to one of those departments.)
SELECT emp.department_emp AS Department, SUM( pro.price ) AS total_department
FROM(SELECT DISTINCT *
FROM employee AS emp, projects AS pro
WHERE emp.number_project = pro.code_project
) AS P
GROUP BY emp.department_emp

Issue in SQL statement to get record combination using "in"

I have a table with 2 columns, say Empname, DepartmentName where one employee may work in multiple departments and vice-versa.
I want to write a query to select the EmpName based on some departments combinations.
For ex. The employee who works under Dept1, Dept2 and Dept3 only (it should select only those employees who works under only 3 departments, in this case)
Here is the query I tried.
Select EmpName, Count(*) as Total from Emp_Departments where DepartmentName in ('Dept1', 'Dept2', 'Dept3') group by EmpName having Total=3
Here the problem is, Any employees who are working any of the above mentioned departments and their total count is 3, it returns their rows also.
Please suggest how can I get the unique combinations only.
You were close - use:
SELECT d.EmpName, COUNT(*) as Total
FROM Emp_Departments d
WHERE d.DepartmentName IN ('Dept1', 'Dept2', 'Dept3')
GROUP BY d.EmpName
HAVING COUNT(DISTINCT d.DepartmentName) = 3