select data from table already selected from - mysql

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.

Related

SQL Compare employees by gender in different departments

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;

Unable to use single-valued column from subquery table join in HAVING clause with aggregate value

Related question upon which I based this question here
For relevant tables and columns (a lot more exist than the following), I have a customer table with cust_id and state columns and an account table with account_id, cust_id, and avail_balance columns.
Example customer table:
| cust_id | state |
|--------:|-------|
| 1 | MA |
| 2 | MA |
| 3 | MA |
| 4 | MA |
| 5 | NH |
| 6 | MA |
| 7 | MA |
| 8 | NH |
| 9 | MA |
| 10 | NH |
| 11 | MA |
| 12 | NH |
| 13 | MA |
Example account table:
| account_id | cust_id | avail_balance |
|-----------:|--------:|--------------:|
| 1 | 1 | 1057.75 |
| 2 | 1 | 500 |
| 3 | 1 | 3000 |
| 4 | 2 | 2258.02 |
| 5 | 2 | 200 |
| 7 | 3 | 1057.75 |
| 8 | 3 | 2212.5 |
| 10 | 4 | 534.12 |
| 11 | 4 | 767.77 |
| 12 | 4 | 5487.09 |
| 13 | 5 | 2237.97 |
| 14 | 6 | 122.37 |
| 15 | 6 | 10000 |
| 17 | 7 | 5000 |
| 18 | 8 | 3487.19 |
| 19 | 8 | 387.99 |
| 21 | 9 | 125.67 |
| 22 | 9 | 9345.55 |
| 23 | 9 | 1500 |
| 24 | 10 | 23575.12 |
| 25 | 10 | 0 |
| 27 | 11 | 9345.55 |
| 28 | 12 | 38552.05 |
| 29 | 13 | 50000 |
Here is the format of the query which I wish to execute.
SELECT a.cust_id, SUM(a.avail_balance) AS cust_tot_bal
FROM
account AS a
INNER JOIN customer c ON a.cust_id = c.cust_id
CROSS JOIN (SELECT MAX(cust_id) AS max_nh_cust_id, MAX(nh_cust_tot_bal) AS max_nh_cust_tot_bal
FROM
(SELECT a.cust_id, SUM(avail_balance) AS nh_cust_tot_bal
FROM
account AS a
INNER JOIN customer c ON a.cust_id = c.cust_id
WHERE
c.state = 'NH'
GROUP BY a.cust_id) AS nh_cust_tot_bal) AS max_nh_cust_tot_bal_t
WHERE c.state = 'MA'
AND a.cust_id > max_nh_cust_id
GROUP BY a.cust_id;
This fails since it is unable to detect max_nh_cust_tot_bal from the previous join.
Expected result for the above example data (the cust_tot_bal column is optional):
| cust_id | cust_tot_bal |
|--------:|-------------:|
| 13 | 50000 |
You can get the maximum cust_id and sum of the customers of state 'NH' with this query:
SELECT MAX(cust_id) max_nh_cust_id,
MAX(t.max_nh_avail_balance) max_nh_avail_balance
FROM (
SELECT a.cust_id, SUM(a.avail_balance) AS max_nh_avail_balance
FROM account a INNER JOIN customer c
ON a.cust_id = c.cust_id
WHERE c.state = 'NH'
GROUP BY a.cust_id
) t
and you can join it like this:
SELECT m.cust_id, m.cust_tot_bal
FROM (
SELECT a.cust_id, SUM(a.avail_balance) AS cust_tot_bal
FROM account a INNER JOIN customer c
ON a.cust_id = c.cust_id
WHERE c.state = 'MA'
GROUP BY a.cust_id
) m
INNER JOIN (
SELECT MAX(cust_id) max_nh_cust_id,
MAX(t.max_nh_avail_balance) max_nh_avail_balance
FROM (
SELECT a.cust_id, SUM(a.avail_balance) AS max_nh_avail_balance
FROM account a INNER JOIN customer c
ON a.cust_id = c.cust_id
WHERE c.state = 'NH'
GROUP BY a.cust_id
) t
) n ON m.cust_id > n.max_nh_cust_id AND m.cust_tot_bal > n.max_nh_avail_balance
See the demo.
Results
> cust_id | cust_tot_bal
> ------: | -----------:
> 13 | 50000

left join same table

I have two tables (Agents) and (Customers)
Agents
| id | agent_name | leader_id|
------------------------------
| 1 | AAA | |
| 2 | BBB | 1 |
| 3 | CCC | 1 |
| 4 | DDD | |
| 5 | EEE | 4 |
Customers
| id | customer_name |agent_id|
-------------------------------
| 1 | ABC1 | |
| 2 | ABC2 | 1 |
| 3 | ABC3 | 3 |
| 4 | ABC4 | 3 |
| 5 | ABC5 | 5 |
I used LEFT JOIN to list all Customers with Agent Name
SELECT *, Customers.id AS id, Agents.id AS aid
FROM Customers LEFT JOIN Agents ON Customers.agent_id = Agents.id
How I can list Customers of specific team using leader_id ?
I think this should solve our problem
SELECT *, Customers.id AS id, Agents.id AS aid FROM Customers LEFT JOIN Agents ON Customers.agent_id = Agents.id where Agents.id = {1} or Agents.leader_id = {1}
Where, {1} could be any value
Correct me if this doesn't workout

Inner Join for four tables is not working?

I have four tables mls_user, mls_category, mls_entry, and bonus_point.
Following are the tables:
mls_user
*--------------------------*
| id | store_id | name |
*--------------------------*
| 1 | 101 | Santosh |
| 2 | 101 | Aman |
| 3 | 102 | Ankit |
| 4 | 101 | Suman |
| 5 | 101 | Ramesh |
*--------------------------*
mls_category
*----------------------------------------*
| cat_no | store_id | cat_type | cat_val |
*----------------------------------------*
| 1 | 101 | running | 1 |
| 2 | 101 | cycling | 4 |
| 3 | 102 | running | 1 |
| 4 | 102 | swiming | 2 |
*----------------------------------------*
mls_entry
*----------------------------------------------------------*
| id | user_id | store_id | category | distance | status |
*----------------------------------------------------------*
| 1 | 1 | 101 | 1 | 5 | Approved |
| 2 | 1 | 101 | 1 | 10 | Approved |
| 3 | 1 | 101 | 2 | 50 | Approved |
| 4 | 1 | 101 | 1 | 10 | Approved |
| 5 | 2 | 101 | 1 | 5 | Approved |
*----------------------------------------------------------*
bonus_point
*---------------------------------------------------------*
| bns_id | user_id | store_id | bonus_points | bonus_type |
*---------------------------------------------------------*
| 1 | 1 | 101 | 100 | fixed |
| 2 | 2 | 101 | 25 | % |
*---------------------------------------------------------*
Now from these four tables, I want below output:
*--------------------------------------------------------------*
| name | points | bonus_points | bonus_type | Total_Points |
*--------------------------------------------------------------*
| Santosh | 25 | 100 | fixed | 125 |
| Aman | 5 | 25 | % | 30 |
| Suman | 0 | 0 | - | 0 |
| Ramesh | 0 | 0 | - | 0 |
| Ankit | 0 | 0 | - | 5 |
*--------------------------------------------------------------*
I am using the following query but this query only shows the value for Santosh and aman
SELECT u.id, u.name, COALESCE(t1.points, 0) AS points, b.bonus_points
FROM mls_user u
LEFT JOIN
(SELECT e.user_id, SUM(e.distance / c.cat_value) AS points
FROM mls_entry e
INNER JOIN mls_category c ON e.store_id = c.store_id AND e.category = c.cat_no
WHERE e.status='approved' AND e.store_id = '101'
GROUP BY e.user_id ) t1 ON u.id = t1.user_id
INNER JOIN bonus_points b ON b.user_id = u.id
WHERE u.store_id = '101'
ORDER by points DESC
So where I am doing wrong in my query, Please help me in this.
In your bonus_points table you have only two entry related to user 1 and 2 (Santosh and aman) if you use INNER JOIN then you obtain only these user
in this case you need left JOIN for bonus_points Too
SELECT u.id, u.name, COALESCE(t1.points, 0) AS points, ifnull(b.bonus_points,0) bonus_point
FROM mls_user u
LEFT JOIN (
SELECT e.user_id, SUM(e.distance / c.cat_value) AS points
FROM mls_entry e
INNER JOIN mls_category c ON e.store_id = c.store_id
AND e.category = c.cat_no
WHERE e.status='approved'
AND e.store_id = '101'
GROUP BY e.user_id
) t1 ON u.id = t1.user_id
LEFT JOIN bonus_points b ON b.user_id = u.id
WHERE u.store_id = '101'
ORDER by points DESC

sum price of childs in other table mysql

I have two table one store data child and parent hierarchy and other paths and descendant
+----------+------------+-----------+
| userid | parent | price |
+----------+------------+------------
| 1 | null | 20 |
| 2 | 1 | 20 |
| 3 | 1 | 20 |
| 4 | 2 | 20 |
| 5 | 2 | 20 |
| 6 | 3 | 20 |
| 7 | 4 | 20 |
+----------+------------+-----------+
I need to get all userid with parent 1 then get descendant in other table and group by userid sum prices
+-------------+---------------+-------------+
| ancestor_id | descendant_id | path_length |
+-------------+---------------+-------------+
| 1 | 1 | 0 |
| 1 | 2 | 1 |
| 1 | 3 | 1 |
| 1 | 4 | 2 |
| 1 | 5 | 2 |
| 1 | 6 | 2 |
| 1 | 7 | 3 |
| 2 | 2 | 0 |
| 2 | 4 | 1 |
| 2 | 5 | 1 |
| 2 | 7 | 2 |
| 3 | 3 | 0 |
| 3 | 6 | 1 |
| 4 | 4 | 0 |
| 4 | 7 | 1 |
| 5 | 5 | 0 |
| 6 | 6 | 0 |
| 7 | 7 | 0 |
+-------------+---------------+-------------+
I have query it sum all childs together
select
sum(b.price)
from webineh_prefix_nodes_paths_tmp a
join webineh_prefix_nodes_tmp b on (b.userid = a.descendant_id)
where a.ancestor_id = 1
this work fine but total sum parent 1
I need to show bellow result for child direct (2,3)
+----------+------------+-
| userid | total |
+----------+------------+
| 2 | 80 |
| 3 | 40 |
+----------+------------+
also in create sqlfiddle my question http://sqlfiddle.com/#!9/9415ed/2
Try this;)
select ancestor_id as userid, sum(b.price) as total
from webineh_prefix_nodes_paths_tmp a
join webineh_prefix_nodes_tmp b
on b.userid = a.descendant_id
where a.ancestor_id in (select userid from webineh_prefix_nodes_tmp where parent = 1)
group by ancestor_id
SQLFiddle Demo
Edited
select ancestor_id as userid, sum(b.price) as total
from webineh_prefix_nodes_paths_tmp a
join webineh_prefix_nodes_tmp b
on b.userid = a.descendant_id
inner join webineh_prefix_nodes_tmp c
on a.ancestor_id = c.userid
and c.parent = 1
group by ancestor_id
SQLFiddle Demo
try this
select sum(b.price) from webineh_prefix_nodes_paths_tmp a join webineh_prefix_nodes_tmp b on (b.userid = a.descendant_id) where a.ancestor_id in ( 1,2,3) GROUP by ancestor_id