My problem is I want to count all the students under n department.
Note: Students has a course and courses has their department (there are many courses in 1 department).
SAMPLE OUTPUT:
+---------+-------------------------------+
| student | department |
+---------+-------------------------------+
| 23| Computer Education Department |
| 67| Basic Education Department |
| 39| Mathematics Department |
| 40| Humanities Department |
| 61| Engineering Department |
| 79| Management Department |
+---------+-------------------------------+
tbl_students
+---------+---------------+--------+
| stud_id | name | course |
+---------+---------------+--------+
| 1 | Jack Owen | 1 |
| 2 | Kirby Lopez | 2 |
| 3 | Justin Minus | 1 |
| 4 | Jerome Noveda | 1 |
+---------+---------------+--------+
2. tbl_courses
+-----------+------------+---------+
| course_id | short_name | dept_id |
+-----------+------------+---------+
| 1 | BSIT | 1 |
| 2 | BSCS | 1 |
| 3 | BEED | 2 |
| 4 | BSED | 2 |
| 6 | BSTHRM | 7 |
| 7 | BLIS | 4 |
| 8 | BSCE | 6 |
+-----------+------------+---------+
3. tbl_department
+---------+-------------------------------+
| dept_id | full_name |
+---------+-------------------------------+
| 1 | Computer Education Department |
| 2 | Basic Education Department |
| 3 | Mathematics Department |
| 4 | Humanities Department |
| 6 | Engineering Department |
| 7 | Management Department |
+---------+-------------------------------+
I think you can do something like this:
SELECT
tbl_department.full_name as department,
COUNT(DISTINCT tbl_students.stud_id) AS student
FROM
tbl_department
JOIN tbl_courses
ON tbl_department.dept_id = tbl_courses.dept_id
JOIN tbl_students
ON tbl_courses.course_id = tbl_students.course
GROUP BY
tbl_department.full_name
SELECT
ISNULL(( SELECT COUNT(*) FROM tbl_courses C
INNER JOIN tbl_students S ON C.course_id = S.course
WHERE C.dept_id = D.dept_id
),0) AS student
,D.full_name AS department
FROM
tbl_department D
I hope that it will work for you.
Related
I need help to write a query that compares the number of male managers and the number of female managers in each department.
tables are as follows.
-- Departments
---------------------------
| dept_id | dept_name |
+---------+---------------+
| 1 | Marketing |
| 2 | Finance |
| 3 | Development |
+---------+---------------+
-- Employees
----------------------------------------
|emp_no | name | gender | hired_date |
+-------+------+----------+------------+
| 1 | John | M | 2017-09-15 |
| 2 | Sara | F | 2018-02-01 |
| 3 | Eli | F | 2019-01-05 |
| 4 | Alex | M | 2019-01-05 |
---------------------------------------------
-- dept_manager
---------------------
|emp_no | dept_id |
+-------+-----------+
| 1 | 3 |
| 3 | 1 |
| 4 | 2 |
| 4 | 3 |
---------------------
Expected Results
-----------------------------------------------------
| dept_id | no_female_managers | no_male_managers |
+------------+---------------------+------------------+
| 1 | 1 | 0 |
| 2 | 0 | 1 |
| 3 | 1 | 1 |
+-----------------------------------------------------+
Any Ideas How I write this in SQL
Just use conditional aggregation:
select dept_id,
sum( gender = 'F' ) as num_f,
sum( gender = 'M' ) as num_m
from Employees e join
dept_manager d
on e.emp_no = d.emp_no
group by dept_id;
with cte as (select emp_no,gender,dept_id
from
Employees e
join dept_manager d
on e.emp_no=d.emp_no)
select
dept_id,
count(case when gender='F' then 1 end) as no_female_managers,
count(case when gender='M' then 1 end) as no_male_managers
from cte
group by dept_id;
student table
|----------------------|
| student_id | name |
|------------|---------|
| 1 | Richard |
| 2 | Emily |
| 3 | Hans |
|------------|---------|
lecturer table
|--------------------|
| lecturer_id | name |
|-------------|------|
| 1 | John |
| 2 | Mike |
|-------------|------|
classes table
|-----------------------------------------------|
| class_id | lecturer_id | material |
|----------|-------------|----------------------|
| 1 | 1 | Basic of algorithm |
| 2 | 1 | Basic of programming |
| 3 | 2 | Database Essentials |
| 4 | 2 | Basic of SQL |
|----------|-------------|----------------------|
attendance table
|-----------------------|
| class_id | student_id |
|----------|------------|
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 3 | 1 |
| 3 | 2 |
| 3 | 3 |
| 4 | 1 |
| 4 | 2 |
|----------|------------|
how to show classes records (from classes table) that not attended by Hans (student) in MySQL?
desired result :
|-----------------------------------------------|
| class_id | lecturer_id | material |
|----------|-------------|----------------------|
| 2 | 1 | Basic of programming |
| 4 | 2 | Basic of SQL |
|----------|-------------|----------------------|
One approach uses EXISTS:
SELECT c.class_id, c.lecturer_id, c.material
FROM classes c
WHERE NOT EXISTS (SELECT 1 FROM attendance a
INNER JOIN student s
ON a.student_id = s.student_id
WHERE a.class_id = c.class_id AND
s.name = 'Hans');
Using joins -
select c.class_id
from attendance a inner join student s on (a.student_id=s.student_id and s.student_id='Hans')
right outer join classes c on (a.class_id=c.class_id)
where a.class_id is null
I have the following tables,
select * from department;
+--------------+--------------+--------+------------+---------------+
| departmentid | name | budget | startdate | administrator |
+==============+==============+========+============+===============+
| 101 | Computer Sci | 1000 | 2010-12-26 | XYZ |
| 102 | ECE | 500 | 2015-02-15 | ABC |
| 103 | EEE | 1500 | 2016-08-25 | PQR |
| 104 | Mech | 2500 | 2017-08-22 | LMN |
+--------------+--------------+--------+------------+---------------+
select * from course;
+----------+-------------------+---------+--------------+
| courseid | title | credits | departmentid |
+==========+===================+=========+==============+
| 1001 | Data structures | 12 | 101 |
| 1002 | Algorithms | 12 | 101 |
| 1003 | Graphics | 20 | 101 |
| 2001 | DSP | 20 | 102 |
| 2002 | Matlab | 20 | 102 |
| 2003 | Maths | 10 | 102 |
| 3001 | CAD | 10 | 104 |
| 4001 | Power electronics | 10 | 103 |
| 4002 | Semi conductors | 20 | 103 |
+----------+-------------------+---------+--------------+
select * from student_grade;
+--------------+----------+----------+-------+
| enrollmentid | courseid | personid | grade |
+==============+==========+==========+=======+
| 1 | 1001 | 1 | A |
| 2 | 1002 | 1 | B |
| 3 | 1003 | 1 | A |
| 4 | 3001 | 3 | A |
| 5 | 3001 | 2 | B |
| 6 | 4001 | 4 | A |
| 7 | 4002 | 4 | A |
+--------------+----------+----------+-------+
select * from person;
+----------+----------+-----------+------------+----------------+
| personid | lastname | firstname | hiredate | enrollmentdate |
+==========+==========+===========+============+================+
| 1 | Goudar | Anil | 2016-08-16 | 2016-08-17 |
| 2 | Goudar | Sunil | 2018-09-16 | 2018-09-27 |
| 3 | Dambal | Abhi | 2018-05-07 | 2018-06-17 |
| 4 | Desai | Arun | 2018-05-07 | 2018-06-17 |
| 5 | Xam | Sam | 2018-12-08 | 2018-12-08 |
| 6 | Chatpati | Mangal | 2018-10-10 | 2018-10-08 |
| 9 | Shankar | Dev | 2018-10-10 | 2018-10-08 |
| 10 | Shankar | Mahadev | 2018-08-10 | 2018-08-11 |
+----------+----------+-----------+------------+----------------+
Now I am trying to get the department details with number of students belonging to the department.
And here is my query,
select d.departmentid, d.name, sg.personid from department d inner join course c on c.departmentid = d.departmentid inner join student_grade sg on sg.courseid = c.courseid;
+--------------+--------------+----------+
| departmentid | name | personid |
+==============+==============+==========+
| 101 | Computer Sci | 1 |
| 101 | Computer Sci | 1 |
| 101 | Computer Sci | 1 |
| 104 | Mech | 3 |
| 104 | Mech | 2 |
| 103 | EEE | 4 |
| 103 | EEE | 4 |
+--------------+--------------+----------+
But I want to get the count(distinct(personid)) for each department like group by clause. But I am getting the error with the following query.
select d.departmentid, d.name, count(distinct(sg.personid)) from department d inner join course c on c.departmentid = d.departmentid inner join student_grade sg on sg.courseid = c.courseid;
Cannot use non GROUP BY column 'departmentid' in query results without an aggregate function
Please help me, where I am going wrong.
you have to use group by as you used aggregate funtion
select d.departmentid, d.name,
count(distinct(sg.personid))
from department d inner join course c on c.departmentid = d.departmentid inner join student_grade sg on sg.courseid = c.courseid;
group by d.departmentid, d.name
Use this:-
select d.departmentid, d.name, count(distinct(sg.personid)) from department d inner join course c on c.departmentid = d.departmentid inner join student_grade sg on sg.courseid = c.courseid group by d.departmentid, d.name;
I have three tables college_details, college_courses, course of which college_courses is an intermediate table for many to many relation ships between college_details and course.
college_details
+------------+--------------+
| college_id | college_name |
+------------+--------------+
| 1 | abc, Nagpur |
| 2 | xyz, Nagpur |
| 3 | mnop, Nagpur |
+------------+--------------+
college_courses
+------------+--------------+
| college_id | course_id |
+------------+--------------+
| 1 | 1 |
| 1 | 5 |
| 2 | 3 |
| 3 | 5 |
+---------------------------+
course
+----------+-------------+
|course_id | course_name |
+----------+-------------+
| 1 | B.E |
| 2 | M.E |
| 3 | M.Tech |
| 4 | B.Tech |
| 5 | M.B.A |
+----------+-------------+
SELECT cd.college_id
, cd.college_name
, c.course_name
FROM college_details AS cd
LEFT
JOIN college_courses AS cc
ON cc.college_id = cd.college_id
LEFT
JOIN course AS c
ON cc.course_id = c.course_id
From the above query I get the following table.
+------------+---------------+-------------+
| college_id | college_name | course_name |
+------------+---------------+-------------+
| 1 | abc, college | be |
| 1 | abc, college | mba |
| 2 | xyz, college | me |
| 3 | mnop, college | btech |
+------------+---------------+-------------+
query -> "SELECT cd.college_id,cd.college_name,GROUP_CONCAT(c.course_name) FROM college_details AS cd LEFT JOIN college_courses AS cc ON cc.college_id = cd.college_id LEFT JOIN course AS c ON cc.college_id = c.course_id ";
And from above query I get the following table.
+------------+--------------+-----------------------------+
| college_id | college_name | GROUP_CONCAT(c.course_name) |
+------------+--------------+-----------------------------+
| 1 | abc, college | be,be,me,btech |
+------------+--------------+-----------------------------+
But what I want is the following table.
+------------+---------------+-------------+
| college_id | college_name | course_name |
+------------+---------------+-------------+
| 1 | abc, college | be,mba |
| 2 | xyz, college | me |
| 3 | mnop, college | btech |
+------------+---------------+-------------+
emp table
+-----+-------+-----+---------+
| eno | ename | dno | salary |
+-----+-------+-----+---------+
| 101 | sam | 1 | 1200.00 |
| 102 | ram | 1 | 1300.00 |
| 103 | alia | 1 | 2500.00 |
| 104 | tina | 2 | 1300.00 |
| 105 | avni | 2 | 1800.00 |
| 106 | suraj | 2 | 2000.00 |
| 107 | chris | 3 | 1500.00 |
| 108 | ben | 3 | 2000.00 |
| 109 | rina | 3 | 3300.00 |
+-----+-------+-----+---------+
Dept table
+-----+-------+-----------+
| dno | dname | location |
+-----+-------+-----------+
| 1 | csc | new delhi |
| 2 | phy | mumbai |
| 3 | chem | hyderabad |
+-----+-------+-----------+
I want to write a query
to display department no. ,department name, average salary of all department
Here dno Is foriegn key in emp table
Dno is a primary key in dept table
I tried many times but sometime there is an error and sometimes wrong output
My desire output is
+-----+-------+-------------+
| dno | dname | avg(salary) |
+-----+-------+-------------+
| 1 | csc | 1666.6666 |
| 2 | phy | 1700.0000 |
| 3 | chem | 2266.6666 |
+-----+-------+-------------+
This is classic 'group by' usage.
Try this:
select d.dno , d.dname, avg(salary)
from employee e LEFT JOIN department d on e.dno=d.dno
GROUP BY e.dno
Here is your query:
SELECT e.dno DNO, d.dname DNAME, AVG(e.salary) SALARY
FROM emp e, dept d
WHERE e.dno = d.dno
GROUP BY DNO