Sql query related to my given tables - mysql

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

Related

Joining NON NULL with NULL Values

Table A
+----+-------+--------------+-------+----------+
| Id | EName | Company Code | State | City |
+----+-------+--------------+-------+----------+
| 1 | Tom | 110 | NC | Ashville |
| 2 | Dick | | | |
| 3 | Harry | | | |
| 4 | Tonny | 667 | MN | St.pauls |
+----+-------+--------------+-------+----------+
Table B
+----+-------+--------------+-------+----------+
| Id | EName | Company Code | State | City |
+----+-------+--------------+-------+----------+
| 1 | Tom | 110 | NC | Ashville |
| 2 | Dick | 111 | MN | Minesota |
| 3 | Harry | 112 | CA | Oregon |
+----+-------+--------------+-------+----------+
O/p
+----+-------+--------------+-------+----------+
| Id | EName | Company Code | State | City |
+----+-------+--------------+-------+----------+
| 1 | Tom | 110 | NC | Ashville |
| 2 | Dick | 111 | MN | Minesota |
| 3 | Harry | 112 | CA | Oregon |
| 4 | Tonny | 667 | MN | St.pauls |
+----+-------+--------------+-------+----------+
Query:
SELECT Ename,
COALESCE(A.ID, B.ID) AS ID
FROM `Table A` AS A,
`Table B` AS B
WHERE A.`id_column_1`=B.`id_column_1`
UNION ALL
SELECT `Ename,`ID`
FROM `Table B`
WHERE `Id` IS NOT NULL
because I want to pick ID from Table B only for records where it doesn’t exist in Table A.Please tell me whats wrong in my query. Thank you.
I think you want to pull the missing information in a from b. If so:
select a.id,
coalesce(a.name, b.name) as name,
coalesce(a.company, b.company) as company,
coalesce(a.state, b.state) as state,
coalesce(a.city, b.city) as city
from a left join
b
on a.id = b.id;

sql inner join on more than 2 tables and aggregate function

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;

SQL Tables - Count rows of table1 based on other 2 tables' conditions

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.

Self-refering table. MySQL

I have another question. I don't seem to fully grasp the concept.
I have a table:
EMPLOYEES
| EMP_NO | APELLIDO | OFFICE | DIRECTOR | START_DATE | SALARY | COMMISSION | DEP_NO |
I have to obtain data of employees who's OFFICE is 'DIRECTOR' (easy, but... ) and I also have to include a column that would return full salary (salary+commission) of all the employees who are theirs subordinates.
Now I know that I need to 'copy' the table so I am able to make it to refer to itself (EMPLOYEES e1, EMPLOYEES e2 etc.). But I am getting really worked up in that obtaining total of salary of those subordinates.
Any thoughts?
(pls help)
EDIT
Sorry guys, true. My fault. OK, so here are some sample data:
+--------+----------+------------+----------+------------+---------+----------+--------+
| EMP_NO | SURNAME | OFFICE | DIRECTOR | START_DATE | SALARY |COMMISSION| DEP_NO |
+--------+----------+------------+----------+------------+---------+----------+--------+
| 7499 | ALONSO |SALESPERSON | 7698 | 1981-02-23 | 1400.00 | 400.00 | 30 |
| 7521 | LOPEZ | EMPLOYEE | 7782 | 1981-05-08 | 1350.50 | NULL | 10 |
| 7654 | MARTIN |SALESPERSON | 7698 | 1981-09-28 | 1500.00 | 1600.00 | 30 |
| 7698 | GARRIDO | DIRECTOR | 7839 | 1981-05-01 | 3850.12 | NULL | 30 |
| 7782 | MARTINEZ | DIRECTOR | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7839 | REY | CEO | NULL | 1981-11-17 | 6000.00 | NULL | 10 |
| 7844 | CALVO |SALESPERSON | 7698 | 1981-09-08 | 1800.00 | 0.00 | 30 |
| 7876 | GIL | ANALIST | 7782 | 1982-05-06 | 3350.00 | NULL | 20 |
| 7900 | JIMENEZ | EMPLOYEE | 7782 | 1983-03-24 | 1400.00 | NULL | 20 |
+--------+----------+------------+----------+------------+---------+----------+--------+
What I need to achieve now is to return table with details of employees GARRIDO and MARTINEZ (EMP_NO 7698 and 7782) along with additional column that would contain total salary of all theirs direct subordinates. Something like that:
+--------+----------+------------+----------+------------+---------+----------+--------+-----------+
| EMP_NO | SURNAME | OFICIO | DIRECTOR | FECHA_ALTA | SALARIO | COMISION | DEP_NO | TOTAL_EMP |
+--------+----------+------------+----------+------------+---------+----------+--------+-----------+
| 7698 | GARRIDO | DIRECTOR | 7839 | 1981-05-01 | 3850.12 | NULL | 30 | 6700 |
| 7782 | MARTINEZ | DIRECTOR | 7839 | 1981-06-09 | 2450.00 | NULL | 10 | 1350.50 |
+--------+----------+------------+----------+------------+---------+----------+--------+-----------+
I believe this should do it. You just need to JOIN to the other rows that you need, then it's a simple matter of grouping to get the aggregate amount that you want.
SELECT
D.emp_no,
D.apellido, -- Why is there one column named in Spanish and the rest in English?
D.office,
D.director,
D.start_date,
D.salary,
D.commission,
D.dep_no,
SUM(COALESCE(S.salary, 0) + COALESCE(S.commission, 0)) AS subordinates_compensation
FROM
Employees D
LEFT OUTER JOIN Employees S ON S.director = D.emp_no
WHERE
D.office = 'Director'
GROUP BY
D.emp_no,
D.apellido,
D.office,
D.director,
D.start_date,
D.salary,
D.commission,
D.dep_no

Display the greater than the average salary by deptid wise

I have two tables one table having deptid, empid, salary and another table having empid, name
Table1
+--------+-------+--------+
| deptid | empid | salary |
+--------+-------+--------+
| coe | 1 | 19000 |
| coe | 2 | 13000 |
| coe | 3 | 14000 |
| igbm | 4 | 15000 |
| igbm | 5 | 21000 |
| igbm | 6 | 31000 |
+--------+-------+--------+
Table2
+-------+------+
| empid | name |
+-------+------+
| 1 | a |
| 2 | b |
| 3 | c |
| 4 | d |
| 5 | e |
| 6 | f |
+-------+------+
average salary
+--------+-------------+
| deptid | avg(salary) |
+--------+-------------+
| coe | 15333.3333 |
| igbm | 22333.3333 |
+--------+-------------+
I need who got more than avg(salary) in deptid wise
| deptid | empid | salary | name |
+--------+-------+--------+----------+
| coe | 1 | 19000 | a |
| igbm | 6 | 31000 | f |
select a.deptid, a.empid, a.salary, b.name from Table1 a, Table2 b where a.empid= b.empid and salary>(select avg(salary) from Table1) group by deptid ;
I used this query it's not working
+--------+-------+--------+----------+
| deptid | empid | salary | name |
+--------+-------+--------+----------+
| coe | 1 | 19000 | a |
| igbm | 5 | 21000 | e |
+--------+-------+--------+----------+
select a.deptid, a.empid, a.salary, b.name from Table1 a, Table 2 where a.empid= b.empid and salary>(select avg(salary) from Table1 order by deptid);
+--------+-------+--------+----------+
| deptid | empid | salary | name |
+--------+-------+--------+----------+
| coe | 1 | 19000 | a |
| igbm | 5 | 21000 | e |
| igbm | 6 | 31000 | f |
+--------+-------+--------+----------+
I use this query, this is take overall average not deptid wise.
You just need to fetch the average of the department, not all:
select a.deptid, a.empid, a.salary, b.name
from Table1 a,
Table2 b
where
a.empid= b.empid and
a.salary>(
select avg(salary)
from Table1 c
where c.deptid = a.deptid
)
Example in SQL Fiddle