MYSQL连接查询无法按预期工作

时间:2018-06-14 19:06:50

标签: mysql join

我基本上有两张桌子:

1)计费费用:这里我们存储餐馆的ID(restid),费用id(chargeid),充电时间(费用发生时的时间),chargeamount(实际费用的金额).charge id是外键billingchargedetails表。

2)billingchargedetails:这里我们存储所有可能费用的详细信息。 chargeid(主键int),chargename(费用名称),perdaycost(每天的费用)

我的期望:

每家餐厅每次收费的总费用汇总报告。

表格中的当前条目是:

select * from billingcharges;
+--------+----------+---------------+--------------+
| restid | chargeid | chargetime    | chargeamount |
+--------+----------+---------------+--------------+
|      1 |        1 | 1536363636363 |          700 |
|      2 |        1 | 1536363636363 |          500 |
|      1 |        1 | 1568789654123 |          500 |
+--------+----------+---------------+--------------+

select * from billingchargedetails;

+----------+--------------------+------------------+
| chargeid | chargename         | chargecostperday |
+----------+--------------------+------------------+
|        1 | Base Charge        |               50 |
|        2 | Spotlight Listing  |               50 |
|        3 | Gold Notification  |              500 |
|        4 | Discount (FIRST50) |               18 |
+----------+--------------------+------------------+

对chargeid的一个简单联接最终没有按照预期给我数量和总和。所以我需要某种形式的左或右外连接,我知道并尝试了很多

我尝试了左连接,如下所示:

select restid, B.chargeid, chargename, count(B.chargeid) as qty,
  sum(ifnull(chargeamount,0)) as total 
from billingcharges as B 
left join billingchargedetails as C on B.chargeid=C.chargeid 
group by restid,B.chargeid;

+--------+----------+-------------+-----+-------+
| restid | chargeid | chargename  | qty | total |
+--------+----------+-------------+-----+-------+
|      1 |        1 | Base Charge |   2 |  1200 |
|      2 |        1 | Base Charge |   1 |   500 |
+--------+----------+-------------+-----+-------+

这确实起作用并且总结了一些东西,但每家餐馆都有丢失的费用。即使它们不存在于计费表中,即左表,我需要它与数量0和总计0。

我尝试了一个右连接,mysql从左表中的非现有条目中选择了一个随机值,如下所示:

select restid, B.chargeid, chargename, count(B.chargeid) as qty,
  sum(ifnull(chargeamount,0)) as total 
from billingcharges as B 
right join billingchargedetails as C on B.chargeid=C.chargeid 
group by restid,B.chargeid;

+--------+----------+-------------------+-----+-------+
| restid | chargeid | chargename        | qty | total |
+--------+----------+-------------------+-----+-------+
|   NULL |     NULL | Spotlight Listing |   0 |     0 |
|      1 |        1 | Base Charge       |   2 |  1200 |
|      2 |        1 | Base Charge       |   1 |   500 |
+--------+----------+-------------------+-----+-------+

预期输出类似于:

 restid chargeid  chargename   qty totalamount
  1        1      Base Charge   2   1200
  1        2      Spotlight     0   0
  1        3      Gold          0   0
  1        4      Discount      0   0
  2        1      Base Charge   1   500
  2        2      Spotlight     0   0
  2        3      Gold          0   0
  2        4      Discount      0   0
  'same as above expected for each restid in billingcharges'

1 个答案:

答案 0 :(得分:1)

在进行外部联接之前,您需要生成餐馆的交叉产品以收取类型费用。

以下内容(但我没有测试过):

SELECT R.restid, D.chargename, COUNT(B.chargeid) AS qty,
  SUM(IFNULL(B.chargeamount, 0)) AS total
FROM (SELECT DISTINCT restid FROM billingcharges) AS R
CROSS JOIN billingchargedetails AS D
LEFT JOIN billingcharges AS B ON R.restid=B.restid AND D.chargeid=B.chargeid
GROUP BY R.restid, D.chargename;

在这个例子中,R和D的交叉积是每个餐馆与每种收费类型交叉。

当然,并非每家餐厅都有这些费用。因此,对于计费费用的外部联接,找到对于餐馆和餐馆的每个相应组合存在的那些行。充电类型。