to show the name of the department which has maximum student count - mysql

There are two tables in total, one is "Department" which has department_name, department_block_number and department_id(primary key) in it and another is "Student" which has student_name,student_id and department_id(foreign key) in it. So based on this scenario, we have to show the name of the department which has maximum student count.
I have tried out something, below you can find my code but it didn't work as expected, so can you help me in rectifying it?
select u
from
(select count(s.student_id) cnt,d.department_name u
from department d
join student s using(department_id)
group by d.department_name
where cnt==(select max(cntt) from (select
count(ss.student_id) cntt,dd.department_name
from department dd
join student ss using(department_id)
group by dd.department_name)
)
);
Note: This problem belongs to SubQueries section.

You only need to get a count of all students in all departments in descending order, then limit to the first result:
SELECT a.`department_name`
count(b.`student_id`) as `num_students`
FROM `Department` a
JOIN `Student` b
ON a.`department_id` = b.`department_id`
GROUP BY `a.department_id`
ORDER BY count(b.`student_id`) DESC
LIMIT 1;

Related

SQL How to find which customer has rented the most films?

I'm struggling with a question that said Which customer has rented the
most films?
I am doing this using the Seikila sample database in MySQL. I have something that joins my tables together and attempts to give me a count but I know its wrong just looking at the actual data in the rental table.
my code is as below
SELECT r.rental_id, cust.customer_id, count(*) as Total_Rentals
FROM rental as r
INNER JOIN customer AS cust on r.customer_id = cust.customer_id
GROUP BY cust.customer_id;
but it tells me for example customer 1 has rented 32 movies, which I know is wrong. what am I doing wrong?
since I was asked for clarification, the database I am using is:
https://dev.mysql.com/doc/sakila/en/
And I am trying to find which customer has rented the most films, I am not entirely sure what my script is actually returning.
Remove the column rental_id from the select list and sort the result by count(*) descending to return the top 1 row:
SELECT cust.customer_id, cust.name, count(*) as Total_Rentals
FROM rental as r
INNER JOIN customer AS cust on r.customer_id = cust.customer_id
GROUP BY cust.customer_id, cust.name
ORDER BY Total_Rentals DESC LIMIT 1
But if you only need the customer's id then there is no need for a join:
SELECT customer_id, count(*) as Total_Rentals
FROM rental
GROUP BY customer_id
ORDER BY Total_Rentals DESC LIMIT 1
You need to join customer and rental, group by customer id (without rental id) and count it:
SELECT cust.customer_id, count(*) as Total_Rentals
FROM rental as r
INNER JOIN customer AS cust on r.customer_id = cust.customer_id
GROUP BY cust.customer_id;
So this code should work. If it doesn't work, that probably means that you have duplicates or other nonconventional issues.

MySQL: Combining two tables with null values does not print 0

In my code I am trying to combine two data tables, Employee and Department. I tried to write a query to print the respective Department Name and number of employees for all departments, even the unstaffed ones. My query looks like this:
SELECT department.name, count(department.name) AS CountOfNAME
FROM department LEFT JOIN employee ON department.dept_id = employee.dept_id
GROUP BY department.name
ORDER BY Count(department.name) DESC, department.name ASC;
And the result is:
Engineering 5
Recruitment 5
Sales 3
Product 2
Finance 1
Operations 1
Research&Development 1
This code works in that it orders departments by number of employees, and then alphabetically, but Finance and Research&Development are not supposed to have any people in them. Is there any way to correctly display those results as having 0 employees? It seems to be a hard thing to do in SQL because of how join works.
The COUNT function should ignore NULL values, giving you a zero count for the finance and research departments. The problem is that you are counting a column in the department table, which always will be non NULL due to that this table is on the left side of the LEFT JOIN. Instead, try counting a column in the employee table:
SELECT department.name,
COUNT(employee.dept_id) AS CountOfNAME
FROM department
LEFT JOIN employee
ON department.dept_id = employee.dept_id
GROUP BY department.name
ORDER BY COUNT(employee.dept_id) DESC,
department.name ASC;
I suggest you create a view for the tallies of employees by department e.g.
CREATE VIEW DepartmentEmployeeTallies
AS
SELECT dept_id, COUNT(*) AS tally
FROM employee
UNION
SELECT dept_id, 0 AS tally
FROM department
WHERE dept_id NOT IN ( SELECT dept_id FROM employee );
Then things resolve to a simple join:
SELECT name, tally
FROM department
NATURAL JOIN
DepartmentEmployeeTallies;

Left outer join vs subquery to include departments with no employees

Lets say I have the following database model:
And the question is as follows:
List ALL department names and the total number of employees in the department. The total number of employees column should be renamed as "total_emps". Order the list from the department with the least number of employees to the most number of employees. Note: You need to include a department in the list even when the department does not currently have any employee assigned to it.
This was my attempt:
SELECT Department.deptname
(SELECT COUNT(*)
FROM Department
WHERE Department.empno = Employee.empno ) AS total_emps
FROM Department
I'm pretty sure my solution is not correct as it won't include departments with no employees. How do you use a left inner join to solve this problem?
The query as you were trying to write it is:
(table creates modified from shree.pat18's sqlfiddle to this sqlfiddle)
create table department (deptno int, deptname varchar(20));
insert into department values (1, 'a'),(2, 'b'),(3, 'c');
create table employee (empno int, deptno int);
insert into employee values (1,1),(2,1),(3,3);
SELECT d.deptname,
(SELECT COUNT(*)
FROM EMPLOYEE e
WHERE d.deptno = e.deptno ) AS total_emps
FROM DEPARTMENT d
ORDER BY total_emps ASC;
(You were counting from DEPARTMENT instead of EMPLOYEE and comparing empno instead of deptno. And you left out a comma.)
(You were asked for every department's name and employee count so this returns that. In practice we would include a presumably unique deptno if deptname was not unique.)
I'm pretty sure my solution is not correct as it won't include
departments with no employees.
Even your answer's version of the query (with the missing comma added) has an outer select that returns a count for every department no matter what the subselect returns. So I don't know why/how you thought it wouldn't.
If you want to use LEFT (OUTER) JOIN then the DEPARTMENT rows with no employees get extended by NULL. But COUNT of a column only counts non-NULL rows.
SELECT d.deptname, COUNT(e.empno) AS total_emps
FROM DEPARTMENT d
LEFT JOIN EMPLOYEE e
ON d.deptno = e.deptno
GROUP BY d.deptno
ORDER BY total_emps ASC;
(Nb the LEFT JOIN version uses more concepts: LEFT JOIN extending by NULL, GROUP BY, and COUNT's NULL behaviour for non-*.)
First off, it's a left outer join. Now, for your query, you want to join the 2 tables based on deptno, then also group by deptno (or deptname, since that is as likely to be unique) to ensure that any aggregation we do is done for each unique department in the table. Finally, the counting is done with the count function, leading to this query:
select d.deptname, count(e.empno) as total_emps
from department d
left join employee e on d.deptno = e.deptno
group by d.deptname
SQLFiddle
Note that since we want all records from department regardless of whether there are matching records in employee or not, department must appear at the left side of the join. We could have done the same thing using a right outer join by swapping the positions of the 2 tables in the join.

SELECT MAX from Counting SQL

I have a problem with extracting data from db. My code looks like:
SELECT MAX(maximum)as Number FROM
(
SELECT department_name, COUNT(employees.employee_id) AS maximum
FROM departments, employees
WHERE departments.department_id=employees.department_id
GROUP BY department_name
)t
and the result is:
Number
1 46
and this is the number of maximum employees in one of the departments.
The problem is that i want to have additional column with the name of the department in wich there is 46 employees. I tried something like:
select department_name, count(employees.employee_id)
from departments, employees
where departments.department_id=employees.department_id
group by department_name
having count(employees.employee_id) =
( SELECT MAX(maxx)FROM
(SELECT department_name, COUNT(employees.employee_id) AS maxx
FROM departments, employees
WHERE departments.department_id=employees.department_id
GROUP BY department_name
);
but it doesn't work. Please help!
try this
SELECT t.department_name, MAX(t.maximum) as Number FROM (
SELECT
department_name,
COUNT(employees.employee_id) AS maximum
FROM departments, employees
WHERE departments.department_id=employees.department_id
GROUP BY department_name
) t
How about this just order your results by maximum in descending order with limit 1,also use modern join syntax query
SELECT d.department_name,
COUNT(e.employee_id) AS maximum
FROM departments d
LEFT JOIN employees e
ON (d.department_id=e.department_id)
GROUP BY d.department_name
ORDER BY maximum DESC
LIMIT 1
This will give you the department name who has the highest count of employees
You could also tack on an additional JOIN to the first query you posted as such:
SELECT TOP 1 d.department_name, MAX(maximum) as Number FROM
(
SELECT department_id AS department_id, COUNT(employees.employee_id) AS maximum
FROM departments, employees
WHERE departments.department_id=employees.department_id
GROUP BY department_id
)t
JOIN departments d ON d.department_id = t.department_id
GROUP BY d.department_name
ORDER BY Number DESC
I tried this with a similar data model in my domain and it works quite nicely.

Sql query to join two table for the final output

Below are the two tables, customer and department. I am struggling very hard to get the output.
I want to write the query which shows only the department name which have maximum number of employees.
Answer should be like this ...
Please help me to write the query.
I would suggest using a sub-query, and then selecting from that query. With the outer select, you order by the number of employees and then limit it to 1. This will give you the top department, but also has the flexibility to be modified to give you a list of the x-number of top departments.
SELECT Dep_Name FROM (
SELECT
d.Dep_Name, COUNT(*) AS `count`
FROM
Departments d
JOIN Employees e ON e.Dep_id = d.Dep_id
GROUP BY
d.Dep_id
) AS q
ORDER BY `count` DESC
LIMIT 1
UPDATE
Per a comment by #Dems, you can actually handle this without a sub-query:
SELECT
d.Dep_Name
FROM
Departments d
JOIN Employees e ON e.Dep_id = d.Dep_id
GROUP BY
d.Dep_id
ORDER BY
COUNT(*) DESC
LIMIT 1
SELECT *
FROM
(
SELECT
d.dep_id,
d.dep_name,
count(c.cus_id) cusCount
FROM
cus c,
dep d
WHERE
c.dep_id = d.dep_id
GROUP BY
d.dep_id,d.dep_name
ORDER BY
cusCount desc)
WHERE
ROWNUM = 1;
I created cus & dep tables in Oracle 10g database and tested my code successfully.
What database are you using, and could you post you code.
There error message shows that your "Order by" clause is wrong.