I have a sample table below,
+-------------+-------------+-------------+----------+------------+---------------------------------+----------+---------------+
| employee_id | first_name | last_name | email | joined_date| title | salary | supervisor_id |
+-------------+-------------+-------------+----------+------------+---------------------------------+----------+---------------+
| 100 | John | King | EM1 | 1984-06-17 | CEO | 14000.00 | NULL |
| 101 | Leona | Kochhar | EM2 | 1993-09-21 | COO | 10000.00 | 100 |
| 102 | Lex | De Haan | EM3 | 1992-01-13 | CFO | 9000.00 | 100 |
| 103 | Alexander | Hunold | EM4 | 2001-04-03 | Gamer | 5000.00 | 102 |
| 104 | Dave | William | EM5 | 2002-05-21 | Gamer | 2000.00 | 103 |
| 105 | David | Austin | EM6 | 2002-06-25 | Gamer | 2800.00 | 103 |
| 106 | Valli | Longwind | EM7 | 2002-02-43 | Gamer | 2800.00 | 103 |
Certain employees are supervisors to other employees in this table. Do note that supervisor_id is the employee_id.
I am tasked to only use SELECT statement to get the employee_id, first_name, salary of the supervisors and the total number of employee under the supervisor.
In my mind, I know that I will need to use some sort of grouping and count. First, COUNT number of employees under each supervisor and second to GROUP BY supervisor ID. I managed to get the output using the simple COUNT and GROUP BY using this query:
SELECT employee_id, COUNT(supervisor_id)
FROM EMPLOYEE
GROUP BY supervisor_id;
This output the supervisor_id and number of employees under the supervisor_id. Which is:
+---------------+----------------------+
| supervisor_id | COUNT(supervisor_id) |
+---------------+----------------------+
| NULL | 0 |
| 100 | 2 |
| 101 | 0 |
| 102 | 0 |
| 103 | 3 |
*Table above slightly modified - this is a sample output
As mentioned, supervisor_id is the employee_id of the employee within the same table. My problem is that I am unable to get this table to display the employee_id, first_name and salary together with the COUNT column. The end result must show the employee_id (linked to supervisor_id), first_name, salary, COUNT.
I have tried this
SELECT employee_id, first_name, salary, COUNT(supervisor_id)
FROM EMPLOYEE
GROUP BY employee_id, first_name, salary, supervisor_id;
But this just returns the original table.
Also when I tried this
SELECT employee_id, first_name, salary, COUNT(supervisor_id)
FROM EMPLOYEE
GROUP BY supervisor_id;
It returns error "Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column" which according to online is how I craft my query (can't mix aggregated and non-aggregated column?).
Can anyone guide me on this? Thanks.
I guess you just need self LEFT JOIN here:
https://www.db-fiddle.com/f/miLeekBXxoiVV1SxuTYc2c/0
SELECT s.employee_id, s.first_name, s.last_name, s.salary, COUNT(e.employee_id)
FROM employee s
LEFT JOIN employee e
ON e.supervisor_id = s.employee_id
GROUP BY s.employee_id, s.first_name, s.last_name, s.salary;
By the way, you've mentioned in comment that you want to use HAVING COUNT() = 0. You should better not use HAVING for this purpose but just change this query to INNER JOIN. It will do the same but more efficient way.
https://www.db-fiddle.com/f/gM6q1UyagrZ4e1EHRvJ1NU/0
Please try this
SELECT E1.supervisor_id,count(E2.supervisor_id) FROM `EMPLOYEE` AS E1
LEFT JOIN (select supervisor_id FROM EMPLOYEE GROUP BY
supervisor_id) AS E2 ON E1.supervisor_id = E2.supervisor_id
GROUP BY E1.supervisor_id
Related
I made this simple database on mysql and with data in my "Work" pivot table, I get the expected results with :
SELECT emp_name, dept_name
FROM Employee e
INNER JOIN Work w ON e.emp_id=w.emp_id
INNER JOIN Department d ON w.dept_id=d.dept_id;
+----------+-----------+
| emp_name | dept_name |
+----------+-----------+
| James | Sales |
| Jack | Marketing |
| James | Finance |
| Tom | Marketing |
+----------+-----------+
But now, if my pivot table is empty, I get NO RESULT as I would expect at least my emp_name list :
+----------+
| emp_name |
+----------+
| James |
| Jack |
| Henry |
| Tom |
+----------+
==> What should be the query for that ???
Thanks for help !
+--------+----------+--------+ Employee table
| emp_id | emp_name | salary |
+--------+----------+--------+
| 1 | James | 2000 |
| 2 | Jack | 4000 |
| 3 | Henry | 6000 |
| 4 | Tom | 8000 |
+--------+----------+--------+
+-------+-----------+ Department table
|dept_id| dept_name |
+-------+-----------+
| 1 | Sales |
| 2 | Marketing |
| 3 | Finance |
+-------+-----------+
+--------+---------+ Work table
| emp_id | dept_id |
+--------+---------+
| 1 | 1 |
| 2 | 2 |
| 1 | 3 |
| 4 | 2 |
+--------+---------+
Use a "left outer join":
SELECT emp_name, dept_name
FROM Employee e
LEFT JOIN Work w ON e.emp_id=w.emp_id
LEFT JOIN Department d ON w.dept_id=d.dept_id;
You seem to want left join:
SELECT emp_name, dept_name
FROM Employee e LEFT JOIN
Work w
ON e.emp_id = w.emp_id LEFT JOIN
Department d
ON w.dept_id = d.dept_id;
Note that this still returns two columns, but the second column is NULL.
In some situations, you need to fabricate a table for the columns.
I wanted a table with 24 columns, one per hour. In the output, I would put counts for actions grouped by day + hour. When there was no action in an hour, I wanted blank, not zero. (Blank stands out more than "0".)
To achieve that, I built a table with just 0..23.
SELECT ...
FROM seq_0_to_23 AS hours
LEFT JOIN the_data ON ...
I'm trying to answer a SQL Leetcode question on Medium Difficulty. The question is asking me to find the people that have the highest salary per department.
I tried using GROUP BY but wasn't able to figure out that approach so I tried to use the PARTITION BY in order to find the max salary for each department. Afterwards, I would add a final WHERE statement where I could filter down to people with a salary that equals the max salary.
This is the query I have so far:
SELECT
Department.Name AS Department,
Employee.Name AS Employee,
Employee.Salary,
MAX(Employee.Salary) OVER (PARTITION BY Department.Name) AS MaxSalary
FROM Employee
LEFT JOIN Department ON Department.id = Employee.DepartmentId
;
There's two tables.
EMPLOYEE TABLE:
+----+-------+--------+--------------+
| Id | Name | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1 | Joe | 70000 | 1 |
| 2 | Jim | 90000 | 1 |
| 3 | Henry | 80000 | 2 |
| 4 | Sam | 60000 | 2 |
| 5 | Max | 90000 | 1 |
+----+-------+--------+--------------+
DEPARTMENT TABLE:
+----+----------+
| Id | Name |
+----+----------+
| 1 | IT |
| 2 | Sales |
+----+----------+
and the correct output should look like this.
CORRECT EXPECTED OUTPUT:
+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT | Max | 90000 |
| IT | Jim | 90000 |
| Sales | Henry | 80000 |
+------------+----------+--------+
Running my current query leads to a runtime error with this message:
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 '(PARTITION BY Department.Name) AS MaxSalary
FROM Employee
LEFT JOIN Department O' at line 7
I've looked over the syntax multiple times so I assume it's a incorrect understanding of how PARTITION BY works. I was expecting that I would see the max salary for each department listed on the right for each individual. Something like this:
+----+-------+--------+--------------+-----------+
| Id | Name | Salary | DepartmentId | MaxSalary |
+----+-------+--------+--------------+-----------+
| 1 | Joe | 70000 | 1 | 90000 |
| 2 | Jim | 90000 | 1 | 90000 |
| 3 | Henry | 80000 | 2 | 80000 |
| 4 | Sam | 60000 | 2 | 80000 |
| 5 | Max | 90000 | 1 | 90000 |
+----+-------+--------+--------------+ -----------+
After achieving that, I was going to add this line:
WHERE Employee.Salary = MaxSalary;
What is the proper way to do this?
You can consider using one of the following:
SELECT D.Name AS Department, E.Name AS Employee, E.Salary
FROM Employee AS E LEFT JOIN Department AS D ON E.DepartmentId = D.id
WHERE (E.Salary = (SELECT MAX(X.Salary) FROM Employee AS X WHERE (X.DepartmentId = E.DepartmentId)));
SELECT D.Name AS Department, E.Name AS Employee, E.Salary
FROM Employee AS E LEFT JOIN Department AS D ON E.DepartmentId = D.id
INNER JOIN (SELECT DepartmentId, MAX(Salary) AS MaxSalary FROM Employee GROUP BY DepartmentId) AS X ON E.DepartmentId = X.DepartmentId AND E.Salary = X.MaxSalary;
I Have a table called EMPLOYEE
| employee_id | name | supervisor_id |
| 123 | Ace Ven | NULL |
| 124 | Ben Agent | 123 |
| 125 | Sam Marks | 123 |
| 126 | Bob Teabag | 125 |
| 127 | Matthew Smith | 125 |
| 128 | Toby McQuire | 123 |
I am trying to find the supervisors and list the amount of employees they have. as you can see the supervisor_id is the same as employee_id. Should come out like this
name | total_employees |
Ace Ven | 3 |
Sam Marks | 2 |
I tried
SELECT supervisor_id, name, count(supervisor_id) AS total_employees FROM EMPLOYEE GROUP BY name HAVING (total_employees > 0);
which didn't work at all (sorry about the format, can't seem to get it to work).
Subquery counts how many records/employees are for each supervisor_id, then this result simply joined table again for retrieving their names:
select your_table.name, t.total_employees from your_table
inner join
(select supervisor_id, count(*) as total_employees from your_table where supervisor_id is not null group by supervisor_id) t
on your_table.employee_id = t.supervisor_id
A simple join will suffice...
Select x.name
, count(*) total
from employee x
join employee y
on y.supervisor_id = x.employee_id
group
by x.employee_id;
EDIT VERSION
EMPLOYEE TABLE
|ID | employee_id | Name |
| 1 | 123 | John Richard |
| 2 | 554 | Daniel Domingo |
educational background
|ID | employee_id | School/institute | date graduated |
| 1 | 123 | highschool | 2007 |
| 2 | 123 | college | 2011 |
| 3 | 554 | college | 2010 |
| 4 | 554 | masteral | 2013 |
job title
|ID | employee_id | Job description |
| 1 | 123 | Free lancer |
| 2 | 554 | admin assistant |
i need to select the latest date info of the employee's educational background
the result would be
result query
|ID | employee_id | Name | Job title | year_graduated | school_institute |
| 1 | 123 | John Richard | Free Lancer | 2011 | college |
| 2 | 554 | Daniel Domingo | Admin Assistant | 2013 | masteral |
Try this:
SELECT *
FROM (SELECT * FROM tableA ORDER BY employee_id, date_graduated DESC) A
GROUP BY employee_id
OR
SELECT a.*
FROM tableA a
INNER JOIN (SELECT employee_id, MAX(date_graduated) maxDate
FROM tableA GROUP BY employee_id
) b ON a.employee_id = b.employee_id AND a.date_graduated = b.maxDate
SELECT employee_id ,MAX([date graduated]) FROM Table GROUP BY [employee_id]
The result is
employee_id | date graduated
----------------------------
123 | 2011
554 | 2013
Subquery will return the maximum date for every employee, you should then join this subquery with your table to return the full row:
SELECT yourtable.*
FROM
yourtable INNER JOIN (SELECT employee_id, MAX(`date graduated`) max_date
FROM yourtable
GROUP BY employee_id) m
ON yourtable.employee_id = m.employee_id
AND yourtable.`date graduated` = m.max_date
for employee 123
SELECT * FROM `your_table`
WHERE employee_id=123
ORDER BY date_graduated DESC LIMIT 1
for employee 554
SELECT * FROM `your_table`
WHERE employee_id=554
ORDER BY date_graduated DESC LIMIT 1
SELECT *
FROM t
GROUP BY employee_id
HAVING date_graduated=max(date graduated)
and you'll get the desired result
Sample data
+----+------------+-------+------------+
| ID | first_name | sales | sale_date |
+----+------------+-------+------------+
| 1 | Lindsey | 32.02 | 2007-03-12 |
| 2 | Nicole | 26.53 | 2007-03-12 |
| 3 | Britney | 11.25 | 2007-03-12 |
| 4 | Ashley | 18.96 | 2007-03-12 |
| 5 | Lindsey | 9.16 | 2007-03-11 |
| 6 | Nicole | 1.52 | 2007-03-11 |
| 7 | Britney | 43.21 | 2007-03-11 |
| 8 | Ashley | 8.05 | 2007-03-11 |
| 9 | Lindsey | 17.62 | 2007-03-10 |
| 10 | Nicole | 24.19 | 2007-03-10 |
| 11 | Britney | 3.40 | 2007-03-10 |
| 12 | Ashley | 15.21 | 2007-03-10 |
| 13 | Lindsey | 0.00 | 2007-03-09 |
| 14 | Nicole | 31.99 | 2007-03-09 |
+----+------------+-------+------------+
I try to find biggest total sales produce by any of this girl
I can find the biggest total sales by using this query
select first_name, sum(sales) as total
from cookie_sales
group by first_name
order by total desc limit 1;
I wonder is there a way to find same value using aggregate max function
If i using something like this
select first_name, max(sum(sales)) from cookie_sales group by first_name;
I will get 1111 Mysql error (Invalid use of group function )
Is there a way?
The query you wrote initially in your question is probably the best approach. I don't understand what would be wrong with that. No need to use subqueries here.
You can try creating a view and then try MAX on that. Something like this:
CREATE VIEW sales_sums AS
select first_name, sum(sales) as total
from cookie_sales
group by first_name
order by total desc limit 1;
SELECT first_name, MAX(total ) AS max_total
FROM sales_sums
GROUP BY first_name
You can use MAX function this way:
SELECT MAX(sum_sales)
FROM (
SELECT first_name, SUM(sales) sum_sales
FROM cookie_sales
GROUP BY first_name
) s
but then if you need to get also the first_name this query will get a little more complicated than your original one.
There is a way; you'll need to be using a MySQL version recent enough to support subqueries (should be anything 5.0 or newer):
SELECT first_name, MAX(total) FROM
(SELECT first_name, SUM(sales) AS total
FROM cookie_sales
GROUP BY first_name
ORDER BY total DESC) sum_query
GROUP BY first_name
LIMIT 0, 1;