问题
I want to return a report that looks like the following:
unit | days | stays | income | charges | mgmt fee | bal
1001 20 6 775.00 1500.00 310.00 0.00
1002 40 14 5000.00 200.00 2100.00 2700.00
1003 50 20 6000.00 10.00 2500.00 3490.00
So the bal is (income - (charges+mgmt fee).
I have tables that look like this:
Unit
id | name | mgmt_fee
1001 blossom 30
1002 charlie 25
1003 deniro 30
1004 archie 20
1005 lilly 25
The mgmt fee is used as a percentage (%)
Reservations
id | unit | arrival | depart | total_price
10111 1001 2014-02-09 2014-02-13 400.00
10012 1001 2014-03-10 2014-03-15 300.00
10145 1002 2014-04-01 2014-04-05 600.00
10043 1003 2014-05-30 2014-06-03 350.00
NOTE: these are not actual data. It is a representation of my fields and what their data may look like, though.
Charges
id | unit | amount | charged_dtm
1 1001 40.00 2014-03-24 19:04:31
2 1001 30.00 2014-03-25 20:51:08
3 1002 100.00 2014-04-05 12:52:25
**There are cases where there may not be charges for a unit in a given month.
I have tried the following query:
SELECT u.name AS unit,
(r.departure-r.arrival) AS days,
COUNT(r.id) AS stays,
SUM(r.total_price) AS income,
SUM(c.amount) AS charges,
(SUM(r.total_price)*(.01*u.mgmt_fee)) AS management,
((SUM(r.total_price)-(SUM(r.total_price)*
(.01*u.mgmt_fee)))-SUM(c.amount)) AS bal
FROM reservations r
JOIN units u ON r.unit = u.id
JOIN charges c ON u.id = c.unit
GROUP BY u.id
It will return one unit and all the other data is totaled together. It is really odd. Now, I tried removing everything and adding on one a time to find the culprit.
I found that up to this query I am good.
SELECT CONCAT(u.unit_name,', "',u.unit_nickname,'"') AS unit,
SUM(r.departure-r.arrival) AS days,
COUNT(r.id) AS stays,
SUM(r.total_price) AS income
FROM reservations r
JOIN units u ON r.unit = u.id
GROUP BY u.id
Once I add in the charges
is when the query goes astray.
Any ideas on how to accomplish my desired result?
回答1:
I think you can't do it all in one go as you are trying to because you want to group/sum items from different tables at the same time. Try this:
select unit, name, stays, days, total_price, charges, mgmt_fee,
(total_price*.01*mgmt_fee) AS management,
(total_price-(total_price*.01*mgmt_fee)-charges) AS bal
from (
select
x.unit,
name,
count(*) as stays,
sum(days) as days,
sum(total_price) as total_price,
charges,
mgmt_fee
from
(select
unit ,
datediff(depart,arrival) as days,
total_price
from
Reservations
) as x
join (
select unit, sum(amount) as charges
from Charges
group by unit
) as y
on x.unit = y.unit
join Unit as u
on u.id = x.unit
group by unit
) as inner_result
Not very tidy or elegant, but I think it works. Note that you will have to be careful if there can be > 1 row in charges per unit. Here is a fiddle to show it running: http://sqlfiddle.com/#!2/f05ba/18
来源:https://stackoverflow.com/questions/23051108/complex-mysql-join-with-group-by