Complex MySQL JOIN with GROUP BY

六眼飞鱼酱① 提交于 2019-12-25 07:16:17

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!