database:
I have a query that needs a name of employee(employee table) whose sum of total_sale(works_with table)>34000.
This means firstly group emp_id by sum(total_sale) and then sum(total_sale)>34000 and then return their names from employee table.
You can use the group by and having as follows:
select e.emp_id, e.first_name, e.last_name
from employee e
join works_with w on w.emp_id = e.emp_id
group by e.emp_id, e.first_name, e.last_name
having sum(w.total_sale)>34000
You can do this with a correlated subquery:
select e.*
from employee e
where (select sum(ww.total_sale)
from works_with ww
where ww.emp_id = e.emp_id
) > 34000;
Because this avoids the outer aggregation, this can often be faster than a method that uses group by explicitly. In particular, this can take advantage of an index on works_with(emp_id, total_sale).
Related
I have two tables: employees and offices.
I want to create a view with all the columns from 'employees', but only two columns of 'offices'.
Also, I want to select only employees who have unique job titles. I'm trying to do it with the following code, but it returns the following error:
#1248 - Every derived table must have its own alias.
I'm using the following query:
SELECT employees.*, offices.officeCode, offices.phone
FROM (
SELECT DISTINCT employees.jobTitle
)
JOIN offices ON employees.officeCode = offices.officeCode
offices table:
employees table:
Desired result:
employeeNumber|jobTitle|firstName|officeCode|city|state|country
including only the first 6 employees from the sample image (as 'Sales Rep' is a repeated jobTitle, the employees with it wouldn't be included).
Current query has a number of issues:
As error indicates, derived table or subquery does not have an alias.
Incomplete SELECT query in derived table without FROM clause: (SELECT distinct emplyees.jobtitle)
Retrieving columns from a table not referenced in data sources of query (i.e., employees)
Therefore, consider joining the two tables with a count check on unique job title:
SELECT e.*, o.officeCode, o.phone
FROM employees e
INNER JOIN offices o
ON e.officeCode = o.officeCode
WHERE e.jobTitle IN
(SELECT sub.jobTitle
FROM employees sub
GROUP BY sub.jobTitle
HAVING COUNT(*) = 1)
With this query:
SELECT e.*
FROM employees e
WHERE NOT EXISTS (SELECT 1 FROM employees WHERE employeeNumber <> e.employeeNumber AND jobTitle = e.jobTitle)
you get all the employees with jobTitle that does not have any other employee.
So join it to offices:
SELECT e.employeeNumber, e.jobTitle, e.firstName, o.*
FROM (
SELECT e.*
FROM employees e
WHERE NOT EXISTS (SELECT 1 FROM employees WHERE employeeNumber <> e.employeeNumber AND jobTitle = e.jobTitle)
) e INNER JOIN offices o
ON e.officeCode = o.officeCode
Just use window functions:
SELECT e.*, o.officeCode, o.phone
FROM (SELECT e.*, COUNT(*) OVER (PARTITION BY jobTitle) as job_cnt
FROM employees e
) e JOIN
offices o
ON e.officeCode = o.officeCode
WHERE job_cnt = 1;
First is employee table, second is works_with table
emp_id is foreign key in works_with table.
What I want to do is to find first name & last name who has total sales more than 100,000.
For example, in first table, emp_id 105 person has 110,000 total sales.
So I want the output to be first name and last name of emp_id 102, 104, 105(whose total sales are more than 100,000).
I tried some nested queries and failed.
Failed code:
SELECT employee.first_name, employee.last_name
FROM employee
WHERE employee.emp_id IN(
SELECT works_with.emp_id, sum(total_sales)
FROM works_with
WHERE works_with.total_sales > 100000
GROUP BY works_with.emp_id);
when using WHERE-IN you must select only one column in subquery
and use aggregates functions for comparison in the HAVING clause they don't work with WHERE.
SELECT employee.first_name, employee.last_name
FROM employee
WHERE employee.emp_id IN(
SELECT works_with.emp_id
FROM works_with
GROUP BY works_with.emp_id
HAVING SUM(total_sales) > 100000
)
also you can use INNER JOIN to get same result
SELECT employee.first_name, employee.last_name,SUM(total_sales) as total_sales
FROM employee
INNER JOIN works_with ON employee.emp_id = works_with.emp_id
GROUP BY employee.emp_id
HAVING total_sales > 100000
Use a JOIN rather than WHERE-IN. And you need to test the sum of all total sales, not the individual total sales. You can do that using HAVING.
SELECT e.first_name, e.last_name
FROM employee AS e
JOIN works_with AS w ON e.emp_id = w.emp_id
GROUP BY e.emp_id
HAVING SUM(w.total_sales) > 100000
I have 2 tables
the 1st one name is (employee) has 3 columns (emp_id, first_name, last_name)
the 2nd table name is (works_with) has also 3 columns (emp_id, client_id, total_sales)
in (works_with) table the same emp_id can be related to different client_id
I need to extract the (first_name) and (last_name) form (employee) table and their (total_sales) of more than 30000 from (work_with) table
I used this code to give me the (emp_id)* with the (total_sales) of more than 30000
SELECT SUM(works_with.total_sales), works_with.emp_id
FROM works_with
WHERE works_with.emp_id IN (SELECT works_with.emp_id
FROM works_with
WHERE works_with.total_sales > 30000)
GROUP BY works_with.emp_id;
and I used this code to give me the (first_name) and (last_name) of those (emp_id)*
SELECT employee.first_name, employee.last_name
FROM employee
WHERE employee.emp_id IN (SELECT works_with.emp_id
FROM works_with
WHERE works_with.total_sales > 30000);
is there a way to join the 2 codes or any other way to have the result that I want
Thank you
Are you just looking for a JOIN?
SELECT e.first_name, e.last_name, SUM(ww.total_sales)
FROM works_with ww JOIN
employee e
ON ew.emp_id = ww.emp_id
WHERE ww.emp_id IN (SELECT ww2.emp_id
FROM works_with ww2
WHERE ww.total_sales > 30000
)
GROUP BY e.emp_id, e.first_name, e.last_name;
The subquery is not needed. It is implementing this logic:
SELECT e.first_name, e.last_name, SUM(ww.total_sales)
FROM works_with ww JOIN
employee e
ON ew.emp_id = ww.emp_id
GROUP BY e.emp_id, e.first_name, e.last_name
HAVING MAX(ww.total_sales) > 30000;
However, I suspect that you want:
SELECT e.first_name, e.last_name, SUM(ww.total_sales)
FROM works_with ww JOIN
employee e
ON ew.emp_id = ww.emp_id
GROUP BY e.emp_id, e.first_name, e.last_name
HAVING SUM(ww.total_sales) > 30000;
Contributing here since I noticed an error in the other answer. See here for how different types of JOINs work: (Link).
SELECT
Employee.First_Name,
Employee.Last_Name,
SUM(WW.Total_Sales)
FROM
Works_With AS WW
INNER JOIN Employee AS Employee
ON Employee.EMP_ID = WW.EMP_ID
GROUP BY
Employee.EMP_ID,
Employee.First_Name,
Employee.Last_Name
HAVING
SUM(WW.Total_Sales) > 30000;
There is a table Employee as below:
I need finds out employees who earn more than their managers and I figure out two methods:
SELECT a.Name AS Employee FROM Employee a, Employee b WHERE a.Salary > b.Salary AND a.ManagerId = b.Id;
SELECT a.Name AS Employee FROM Employee a INNER JOIN Employee b ON a.Salary > b.Salary AND a.ManagerId = b.Id;
Both of them work well and have close speed.
What's the difference between them? Thanks.
Those queries are equivalent. But you should use the join syntax instead of commas in the from clause. INNER JOIN ON vs WHERE clause
Here's an alternative option which might have a better performance using exists:
select e.Name AS Employee
from employee e
where exists (
select 1
from employee e2
where e.managerid = e2.id and e.salary > e2.salary
)
Here are my tables:
employees
id
name
salary
dept_id
departments
id
name
SELECT employees.id, employees.name, empolyees.dept_id, departments.id,
departments.name
FROM employees, departments
WHERE employees.dept_id = departments.dept_id
ORDER BY employees.name;
Am I joining these two tables right?
Better use the explicit join syntax
SELECT e.id, e.name, e.dept_id, d.id, d.name
FROM empolyees e
INNER JOIN departments d ON e.dept_id = d.id
ORDER BY e.name
And you used departments.dept_id which does not exist. It is departments.id
could say:
SELECT e.id, e.name, empolyees.dept_id, d.id, d.name
FROM employees e
inner join departments d on e.dept_id = d.dept_id
ORDER BY e.name;