SQL Compare employees by gender in different departments - mysql

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;

Related

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.

select data from table already selected from

I have a few tables that I am trying to get data out of. I need to link the cust and emp tables to the sale table. Then, in turn, get the names of the cust and emp from the person table.
I am stuck
Data looks like:
Table SALES
+--------+--------+-------+-------+
| saleID | custID | empID | total |
|--------+--------+-------+-------|
| 1 | 1 | 1 | 3.00 |
|--------+--------+-------+-------|
| 2 | 2 | 3 | 6.00 |
|--------+--------+-------+-------|
| 3 | 3 | 1 | 9.00 |
|--------+--------+-------+-------|
| 4 | 2 | 2 | 2.00 |
|--------+--------+-------+-------|
| 5 | 3 | 3 | 1.00 |
|--------+--------+-------+-------+
Table cust
+--------+---------+----------+
| custID | company | personID
+--------+---------+----------+
| 1 | comp1 + 2 |
+--------+---------+----------+
| 2 | comp2 + 4 |
+--------+---------+----------+
| 3 | comp3 + 6 |
+--------+---------+----------+
Table emp
+--------+----------+----------+
| custID | username | personID |
+--------+----------+----------+
| 1 | emp1 | 1 |
+--------+----------+----------+
| 2 | emp2 | 3 |
+--------+----------+----------+
| 3 | emp3 | 5 |
+--------+----------+----------+
Table person
+----------+------+
| personID | name |
+----------+------+
| 1 | per1 |
+----------+------+
| 2 | per2 |
+----------+------+
| 3 | per3 |
+----------+------+
| 4 | per4 |
+----------+------+
| 5 | per5 |
+----------+------+
| 6 | per6 |
+----------+------+
I want to query to give me this:
+--------+--------+----------+-------+---------+-------+
| saleID | custID | custName | empID | empName | total |
+--------+--------+----------+-------+---------+-------+
| 1 | 1 | per2 | 1 | per1 | 3.00 |
+--------+--------+----------+-------+---------+-------+
| 2 | 2 | per4 | 3 | per5 | 6.00 |
+--------+--------+----------+-------+---------+-------+
| 3 | 3 | per6 | 1 | per1 | 9.00 |
+--------+--------+----------+-------+---------+-------+
| 4 | 2 | per4 | 2 | per3 | 2.00 |
+--------+--------+----------+-------+---------+-------+
| 5 | 3 | per6 | 3 | per5 | 1.00 |
+--------+--------+----------+-------+---------+-------+
Simple JOINs should do the trick:
SELECT
a.saleID,
b.custID,
p1.name as custName,
c.empID,
p2.name as empName,
a.total
FROM SALES a
JOIN cust b
ON a.custID = b.custID
JOIN emp c
ON c.custID = a.custID AND c.empID = a.empID
JOIN person p1
ON p1.personID = b.personID
JOIN person p2
ON p2.personID = c.personID
ORDER BY saleID
Try this out:
select a.saleID, a.custID, d.name as custName,a.empID,e.nname as empName,
a.total
from
sales a
left join
cust b
on a.custID = b.custID
left join
emp c
on a.empID = C.custID
left join
person d
on b.personID = d.personID
left join
person e
on c.personID = e.personID
Let me know in case of any queries.

Sql query related to my given tables

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

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

MYSQL: Separate products into columns

This is in relation to my previous post MYSQL: Get quantity per product in each order.
Using the query below, it generates a table of:
SELECT o.order_id, o.username, op.product_id, SUM( op.quantity ) as quantity
FROM `orders` o JOIN
orders_products op
ON op.order_id = o.order_id
GROUP BY op.product_id, o.order_id
ORDER BY o.order_id, op.product_id;
_______________________________________________
| order_id | username | product_id | quantity |
-----------------------------------------------
| 1 | bill | 1 | 5 |
-----------------------------------------------
| 1 | bill | 2 | 3 |
-----------------------------------------------
| 1 | bill | 3 | 2 |
-----------------------------------------------
| 2 | sally | 1 | 2 |
-----------------------------------------------
| 3 | jeff | 1 | 6 |
-----------------------------------------------
| 3 | jeff | 2 | 7 |
-----------------------------------------------
As seen above, each new product_id is assigned its own row. Is it possible to have additional columns for each product_id instead of rows generating an output same as the one below?
_______________________________________________________________________
| order_id | username | product_qty_1 | product_qty_2 | product_qty_3 |
-----------------------------------------------------------------------
| 1 | bill | 5 | 3 | 2 |
-----------------------------------------------------------------------
| 2 | sally | 2 | 0 | 0 |
-----------------------------------------------------------------------
| 3 | jeff | 6 | 7 | 0 |
-----------------------------------------------------------------------
My tables:
-- Orders
_______________________
| order_id | username |
-----------------------
| 1 | bill |
-----------------------
| 2 | sally |
-----------------------
| 3 | jeff |
-----------------------
-- Products
___________________
| id | product |
-------------------
| 1 | Table |
-------------------
| 2 | Chair |
-------------------
| 3 | Mouse |
-------------------
-- Order Products
___________________________________________
| id | order_id | product_id | quantity |
-------------------------------------------
| 1 | 1 | 1 | 5 |
-------------------------------------------
| 2 | 1 | 2 | 3 |
-------------------------------------------
| 3 | 1 | 3 | 2 |
-------------------------------------------
| 4 | 2 | 1 | 2 |
-------------------------------------------
| 5 | 3 | 1 | 6 |
-------------------------------------------
| 6 | 3 | 2 | 7 |
-------------------------------------------
If you know the products in advance, you can use conditional aggregation:
SELECT o.order_id, o.username,
SUM(CASE WHEN op.product_id = 1 THEN op.quantity ELSE 0 END) as quantity1,
SUM(CASE WHEN op.product_id = 2 THEN op.quantity ELSE 0 END) as quantity2,
SUM(CASE WHEN op.product_id = 3 THEN op.quantity ELSE 0 END) as quantity3
FROM `orders` o JOIN
orders_products op
ON op.order_id = o.order_id
GROUP BY o.order_id
ORDER BY o.order_id;
If you don't know the product ids, then you would have to use dynamic SQL, or perhaps use GROUP_CONCAT() to create a string with the information you want.