How to join these two tables in MySQL? - mysql

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;

Related

MySQL: Get the count and avg from join tables

I have the following 5 tables:
employees as e
dept_manager as dm
departments as d
titles as t
salaries as s
I would like to know how many male and female managers we have, along with the avg salary per gender within a department.
I wrote the query below but the numbers don't add up:
select
d.dept_name,
count(e.gender),
avg(salary)
from employees as e
Join dept_manager as dm on e.emp_no = dm.emp_no
Join departments as d on d.dept_no = dm.dept_no
Join titles as t on e.emp_no = t.emp_no
Join salaries as s on dm.emp_no = s.emp_no
where t.title ='manager'
group by d.dept_name, e.gender
order by d.dept_name ASC;

sql query company database

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).

List the firstname, lastname of employees who are Sales Reps who have no assigned customers

The employeenumber data in the employeestable is similar to the salesrepemployeenumber in the customers tablecustomers table.
Some employees are not in the customers table.
How do I find the employees who are not in the salesrepemployeenumber row but presnt as employeenumber in the employees table .
note the data in the two rows is the same . and right and left join are not working
this is my code
select e.firstname, e.lastname, e.employeeNumber
from employees e
right join customers c on e.employeeNumber=c.salesRepEmployeeNumber
where c.salesrepemployeeNumber is null
Try using left join
select e.firstname, e.lastname, e.employeeNumber
from employees e
LEFT join customers c on e.employeeNumber=c.salesRepEmployeeNumber
where c.salesrepemployeeNumber is null
If I understood correctly, you need employees which are not in customers table as salesRep. How about the following?
select e.firstname, e.lastname, e.employeeNumber
from employees e
where e.employeeNumber not in (select c.salesRepEmployeeNumber from customers c)

Error Number: 1137 Can't reopen table: 'd'

select employee_id, first_name, last_name, department_name, location_id
from employees as e, departments as d
where d.department_id = e.department_id and (location_id)
in
(select location_id
from departments
where department_name = 'Finance')
It seems you don't need subquery to filter location_id
select employee_id, first_name, last_name, department_name, location_id
from employees as e join departments as d on d.department_id = e.department_id
where location_id in (select location_id from departments where department_name = 'Finance')
Note: it's better to use explicit join instead of comma separated join
You could use an inner join instead of an IN clause
select employee_id
, first_name
, last_name
, department_name
, d.location_id
from employees as e
INNER JOIN departments as d ON d.department_id = e.department_id
INNER JOIN ( select location_id
from departments
where department_name = 'Finance') t ON t.location_id = d.location_id
And for readability you should us explicit JOIN syntax, and not implicit syntax based on WHERE.

Sql numbers of employees by department

I have 2 tables employees(id, first_name, last_name, salary, department_id_ and department(id, name) and I want to show number of employees in each department.
I have this question here:
SELECT department.name, COUNT(*) AS 'employees_number'
FROM department
LEFT JOIN employees
ON employees.department_id = department.id
GROUP BY department.id, department.name;
But for some reason, in departments where I have no people, it shows a number of employees as 1. Any idea why this is happening?
With an outer join you still get a result row when no match in the outer table is found. Only all employee column values are null then.
So rather than count the records, you want to count matched records, i.e. where an employee was found and its data is not null. So Count a column in the employee table (nulls are not counted, when counting a column or expression). E.g. use COUNT(e.department_id) or COUNT(e.id):
SELECT d.name, COUNT(e.id) AS employees_number
FROM department d
LEFT JOIN employees e ON e.department_id = d.id
GROUP BY d.id, d.name;
What I prefer though, is to aggregate/count before joining. The query looks a bit more complicated, but is less prone to errors on future query changes:
SELECT d.name, COALESCE(e.how_many, 0) AS employees_number
FROM department d
LEFT JOIN
(
SELECT department_id, COUNT(*) AS how_many
FROM employees
GROUP BY department_id
) e ON e.department_id = d.id;
As it's one aggregated column only you want, you can move the subquery to your SELECT clause and get thus a simpler query:
SELECT
d.name,
(
SELECT COUNT(*)
FROM employees e
WHERE e.department_id = d.id
) AS employees_number
FROM department d;
Using SUM instead of COUNT also can give you what you want:
SELECT
department.name,
SUM(CASE WHEN employees.id IS NOT NULL THEN 1 ELSE 0 END) AS 'employees_number'
FROM department
LEFT JOIN employees
ON employees.department_id = department.id
GROUP BY department.id, department.name;
SQL Fiddle:
http://sqlfiddle.com/#!9/8b8976/1
select department.name, count(employee.id) as co from
department left join employee on
department.id = employee.dept_id group by department.name
order by co desc, department.name asc