Inner Join for four tables is not working? - mysql

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

Related

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

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.

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

How to count join on other table

How to count base on the others table sum
I have this tables
CARDS
| ID | Name |
---------------------
| 1 | Nice |
| 2 | Wow |
| 3 | Lol |
| 4 | Ohyeah |
| 5 | Olala |
VOTES
ID | *card_id* | *user_id* | vote |
-------------------------------------------------
1 | 1 | 1 | -1 |
2 | 2 | 2 | -1 |
3 | 2 | 4 | 1 |
4 | 2 | 5 | 1 |
5 | 3 | 2 | 1 |
6 | 3 | 1 | 1 |
RESULT QUERY WHAT I WANT
| card_id | total_votes |
-------------------------------
| 1 | -1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 0 |
| 5 | 0 |
and this is what I've tried
SELECT c.*, COALESCE(SUM(v.vote),0) as vote_count
FROM cards c
LEFT JOIN votes v ON c.id = v.card_id
I don't where I mistake, please need help
You dont need subquery, just the group by
SQL Fiddle Demo
SELECT c.`ID`,
COALESCE(Sum(v.vote), 0) AS total_votes
FROM cards c
LEFT JOIN votes v
ON c.id = v.`card_id`
GROUP BY c.`ID`;
OUTPUT
| ID | total_votes |
|----|-------------|
| 1 | -1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 0 |
| 5 | 0 |
You should select all votes and group them by card_id. There u can simply use SUM function.
SELECT c.id, COALESCE(SUM(v.vote), 0)
FROM VOTES
LEFT JOIN c ON v.card_id = c.ID
GROUP BY v.card_id
Following query will do the trick
select c.id, sum(v.vote)
from cards c, votes v
where c.id = v.card_id
group by c.id

Select average from join MYSQL

I am trying to get an average on the last join:
INNER JOIN rating r
ON r.rid = (SELECT MAX(rid) FROM rating WHERE uid = u.uid ORDER BY rid DESC LIMIT 1)
I am having some problems getting it to give me a rating with 1 decimal like 4.3 in rating. How can i do this in a simple way?
SELECT p.uid, u.name, u.description, u.url, u.picurl, u.mapurl, p.pid, p.price, r.rid, r.rating FROM utested u
INNER JOIN price p
ON p.pid = (SELECT MAX(pid) FROM price WHERE uid = u.uid ORDER BY uid DESC LIMIT 1)
INNER JOIN rating r
ON r.rid = (SELECT MAX(rid) FROM rating WHERE uid = u.uid ORDER BY rid DESC LIMIT 1)
ORDER BY u.name;
I have created a sql fiddle so you can try out the queries.
http://sqlfiddle.com/#!2/93b771/1
Consider the following. How does this result differ from the desired result?
+-----+------------+-------------+----------+------------+--------------+-----+-------+-----+--------+
| uid | name | description | url | picurl | mapurl | pid | price | rid | rating |
+-----+------------+-------------+----------+------------+--------------+-----+-------+-----+--------+
| 5 | Havana Pub | | | | | 35 | 74 | 11 | 5 |
| 3 | Hos Naboen | | | | | 33 | 74 | 9 | 5 |
| 2 | Javel | Musikk | javel.no | pic.jave.. | map.javel.no | 38 | 88 | 8 | 5 |
| 1 | Kick | Yay | kick.no | http://p.. | map.kick.no | 31 | 74 | 15 | 1 |
| 6 | Leopold | | | | | 36 | 74 | 12 | 5 |
| 4 | Victoria | | | | | 37 | 75 | 10 | 5 |
+-----+------------+-------------+----------+------------+--------------+-----+-------+-----+--------+
OK. I'm going to take a wild stab in the dark here...
SELECT p.uid
, u.name
, u.description
, u.url
, u.picurl
, u.mapurl
, p.pid
, p.price
, AVG(r.rating) rating
FROM utested u
JOIN price p
ON p.uid = u.uid
JOIN ( SELECT uid, MAX(pid) latest_price FROM price GROUP BY uid ) px
ON px.uid = p.uid
AND px.latest_price = p.pid
JOIN rating r
ON r.uid = u.uid
GROUP
BY u.name;
+-----+------------+-------------+----------+--------------+--------------+-----+-------+--------+
| uid | name | description | url | picurl | mapurl | pid | price | rating |
+-----+------------+-------------+----------+--------------+--------------+-----+-------+--------+
| 5 | Havana Pub | | | | | 35 | 74 | 5.5000 |
| 3 | Hos Naboen | | | | | 33 | 74 | 4.0000 |
| 2 | Javel | Musikk | javel.no | pic.javel... | map.javel.no | 38 | 88 | 5.0000 |
| 1 | Kick | Yay | kick.no | http://pri.. | map.kick.no | 31 | 74 | 3.4000 |
| 6 | Leopold | | | | | 36 | 74 | 3.5000 |
| 4 | Victoria | | | | | 37 | 75 | 4.0000 |
+-----+------------+-------------+----------+--------------+--------------+-----+-------+--------+