Is this a proper MySql query - mysql

Im trying to get the first 100 rows consisting of First Name, Last Name, Department Name, Title, Salary from the employee database but not sure if Im doing it correctly. I tried the query below and it seems to work but doesn't feel right specially since there are no ON statements for the last 2 joins. Is it correct and is there a more efficient way I can perform this query.
This is the link to the database tables graph to give you a idea of the database.
https://dev.mysql.com/doc/employee/en/images/employees-schema.png
My query that seems to work:
SELECT e.first_name, e.last_name, dpn.dept_name, t.title, s.salary
FROM employees e, dept_emp dp
INNER JOIN departments dpn
ON dp.dept_no = dpn.dept_no
INNER JOIN salaries s
INNER JOIN titles t
LIMIT 100;
I tried the code below but kept getting error "#1054 - Unknown column 'e.emp_no' in 'on clause' " starting for the second to last ON statement.
SELECT e.first_name, e.last_name, dpn.dept_name, t.title, s.salary
FROM employees e, dept_emp dp
INNER JOIN departments dpn
ON dp.dept_no = dpn.dept_no
INNER JOIN salaries s
ON e.emp_no = salaries.emp_no
INNER JOIN titles t
ON e.emp_no = t.emp_no
LIMIT 100;
Thanks!

You have no join clause between e table and dp table eg:
SELECT e.first_name, e.last_name, dp.dept_name, t.title, s.salary
FROM employees e
INNER JOIN dept_emp dp on e.emp_no = dp.emp_no
INNER JOIN departments dpn ON dp.dept_no = dpn.dept_no
INNER JOIN salaries s ON e.emp_no = s.emp_no
INNER JOIN titles t ON e.emp_no = t.emp_no
LIMIT 100;

Try it like this:
SELECT e.first_name, e.last_name, departments.dept_name, titles.title, salaries.salary
FROM employees e
INNER JOIN dept_emp
ON e.emp_no = dept_emp.emp_no
INNER JOIN departments
ON dept_emp.dept_no = departments.dept_no
INNER JOIN titles
ON e.emp_no = titles.emp_no
INNER JOIN salaries
ON e.emp_no = salaries.emp_no
LIMIT 100;

The "On" clause in inner join is optional. If you do not have "On" clause it means a "cross join".
If what you want is inner join, then you should have an "On" clause and specify which columns should equate.

SELECT e.first_name,
e.last_name,
departments.dept_name,
titles.title,
salaries.salary
FROM employees e
LEFT JOIN dept_emp
ON e.emp_no = dept_emp.emp_no
LEFT JOIN departments
ON dept_emp.dept_no = departments.dept_no
LEFT JOIN titles
ON e.emp_no = titles.emp_no
LEFT JOIN salaries
ON e.emp_no = salaries.emp_no
LIMIT 100;
try this one too because
INNER JOIN: returns rows when there is a match in all tables.
LEFT JOIN: returns all rows from the left table, even if there are no matches in the right table.

Related

Where do I place the DESC command in my query? I do not get it

enter image description hereIt is a sql query on the github "employees" database. I have to calculate the average salary that each employee has received, order it from highest to lowest and indicate the job title of the employee. I have used this statement and it works fine, but I can't locate DESC, I can't get it to work for me. I am learning and it is the first database that I use with so many tables. Let's see if someone can help me. Thanks
select
concat (employees.first_name,' ',employees.last_name) as 'nombre_completo',
salaries.emp_no as 'numero_empleado',
#departments.dept_no as 'numero_departamento',
departments.dept_name as 'nombre_departamento',
avg (salaries.salary) as 'avg_salario'
from salaries
inner join dept_emp on salaries.emp_no = dept_emp.emp_no
inner join employees on salaries.emp_no = employees.emp_no
inner join departments on dept_emp.dept_no = departments.dept_no
group by salaries.emp_no,dept_emp.dept_no
I tried various methods. Sorry if I don't understand well, I'm using a translator and I'm new to sql, I'm learning
select
concat (employees.first_name,' ',employees.last_name) as
'nombre_completo',
salaries.emp_no as 'numero_empleado',
#departments.dept_no as 'numero_departamento',
departments.dept_name as 'nombre_departamento',
avg (salaries.salary) as 'avg_salario'
from salaries
inner join dept_emp on salaries.emp_no = dept_emp.emp_no
inner join employees on salaries.emp_no = employees.emp_no
inner join departments on dept_emp.dept_no = departments.dept_no
group by salaries.emp_no,dept_emp.dept_no
order by salary DESC
select
concat (employees.first_name,' ',employees.last_name) as
'nombre_completo',
salaries.emp_no as 'numero_empleado',
#departments.dept_no as 'numero_departamento',
departments.dept_name as 'nombre_departamento',
salaries.salary as 'salario'
avg (salaries.salary) as 'avg_salario'
from salaries
inner join dept_emp on salaries.emp_no = dept_emp.emp_no
inner join employees on salaries.emp_no = employees.emp_no
inner join departments on dept_emp.dept_no = departments.dept_no
group by salaries.emp_no,dept_emp.dept_no
order by salary DESC
select
concat (employees.first_name,' ',employees.last_name) as
'nombre_completo',
salaries.emp_no as 'numero_empleado',
#departments.dept_no as 'numero_departamento',
departments.dept_name as 'nombre_departamento',
salaries.salary as 'salario'
avg (salaries.salary) as 'avg_salario'
from salaries
inner join dept_emp on salaries.emp_no = dept_emp.emp_no
inner join employees on salaries.emp_no = employees.emp_no
inner join departments on dept_emp.dept_no = departments.dept_no
group by salaries.emp_no,dept_emp.dept_no
order by salario DESC

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;

MySQL JOIN working properly only when selecting every column with wildcard

This was probably asked a few times, but I couldn't find an answer. While doing JOIN on two tables, I encounter a problem.
First table is named "Employees" and another "Orders".
I'm trying to create a query, which will give me the output like:
order_id (from Orders) | first_name (from Employees) | last_name (from Employees)
The queries I use are:
SELECT * FROM Orders
LEFT JOIN Employees e on Orders.employeeid = e.EmployeeID;
or full join:
SELECT * FROM Orders
LEFT JOIN Employees e on Orders.employeeid = e.EmployeeID
UNION
SELECT * FROM Employees
RIGHT JOIN Orders o on Employees.EmployeeID = o.employeeid;
both work just fine, giving me the same results. Unless I select which columns I wish to extract. So query like that:
SELECT Orders.orderid, e.first_name, e.last_name FROM orders
LEFT JOIN Employees e on orders.employeeid = e.EmployeeID;
Gives me totally different results. Eg. first 100 orderids have same employee name, then another 100 different one and so on (only 4 employees overall, should be 9).
What am I doing wrong?
EDIT (screenshots added):
Orders table:
Employees table:
Output when doing full join, everything seems to be ok:
Left join (or any other join, looks the same). Some orders seem to be ommited, but overall only 4 employees are listed.
I don't know your data, but I think you want:
SELECT o.orderid, e.first_name, e.last_name FROM orders o INNER JOIN Employees e ON o.employeeid = e.employeeId
where o.employeeid != null
Order by o.orderid
It's hard to tell without seeing some data samples.
But here are a few points:
With LEFT JOIN you get 'only 4 employees overall, should be 9' -- I assume there are 5 employees that do not have any order.
In the 'full join' you get mixed columns, the correct way should be
SELECT * FROM Orders
LEFT JOIN Employees e on Orders.employeeid = e.EmployeeID
UNION
SELECT * FROM Orders
RIGHT JOIN Employees e on Orders.employeeid = e.EmployeeID
Otherwise there should be no difference in the output if you specify the columns, as opposed to *.
If
SELECT * FROM Orders
LEFT JOIN Employees e on Orders.employeeid = e.EmployeeID
is returning the correct set of results, then this should probably work:
Select orderid, FirstName, LastName from (SELECT * FROM Orders
LEFT JOIN Employees e on Orders.employeeid = e.EmployeeID LIMIT 999999) as joinedTable

Query Fine Tuning

I am fairly new to sql and would like to ask for your assistance regarding this query. Is there another way to rewrite this?
Select *
From emp
Where emp_no IN (
Select emp_no
From dept_emp
Where dept_no = 'd002'
);
Any assistance is greatly appreciated.
Thanks.
You can use exists:
select *
from emp
where exists(
select 1 from dept_emp where dept_emp.emp_no = emp.emp_no and dept_no = 'd002'
)
also maybe inner join work:
select emp.*
from emp
join dept_emp
on dept_emp.emp_no = emp.emp_no
and dept_no = 'd002'
you can use an inner join
select *
from emp
inner join (
Select emp_no
From dept_emp
Where dept_no = 'd002'
) t on emp_no.id = t.emp_no
or without subselect
select *
from emp
inner join dept_emp on emp_no.id = dept_emp.emp_no
and dept_emp.dept_no = 'd002'
You can use join like this:
select * from emp e, dept_emp d where e.emp_no = d.emp_no and d.dept_no = 'd002'
- If have the relation between two tables best-way you can used join. other wise you can used inner query (sub select)
- When you used join in RDBMS it will faster that inner query.
- join must be indexed based like: primary key and foreign key. Other wise executing cost will be high. non-index query time consumed maximum.

How to join these two tables in 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;