【问题标题】:Mysql, 3 tables 2 group byMysql,3表2分组
【发布时间】:2014-01-20 15:47:15
【问题描述】:

我有 3 张桌子,学生、家庭和费用。有些家庭有不止一个孩子。费用记录在费用表中。家庭全年支付许多款项。 我想按家庭对孩子的数量进行分组,并得到每个家庭支付的总金额。 我的查询:

SELECT student.Family_ID, family.Family_Name, count(*) as kids_numb, sum (Amount)  as Paid_Amount        
      FROM student, family, fee 
      WHERE student.Family_ID = family.Family_ID
      AND fee.Family_ID = family.Family_ID
      AND student.Status ='1'
      GROUP BY student.Family_ID;

我需要对类似的东西进行排序:

姓氏 | # 孩子 |费用 |付费 |平衡 -------------------------------------------------- -- 黎巴嫩 | 1 | 425 | 200 | 225 拉沃伊 | 2 | 700 | 150 | 550 午睡 | 1 | 425 | 0 | 425 专业 | 3 | 900 | 300 | 600

【问题讨论】:

  • 请显示准确的表模式(例如,SHOW CREATE TABLE <table_name> 的结果)。 amount 是否属于 fee 表? fees 的总价值应该来自哪里?
  • 是的金额属于费用表。
  • 只有一件事,如果家庭的所有孩子的状态 =0,则查询仍会返回一行。在演示中,假设 family_id (3) 的两个孩子都离开了学校(状态 = 0),然后查询返回一行,其中 NULL 作为孩子数。谢谢
  • 太棒了!有效。你真是个好人。发自内心的感谢你
  • 很抱歉再次回到这里。我想知道是否可以添加“WITH ROLLUP”来计算总金额。谢谢

标签: mysql sql


【解决方案1】:

已更新,基于您的 cmets。

试试这个方法

SELECT m.family_id, m.family_name, s.kids_numb, COALESCE(f.paid_amount, 0) paid_amount
  FROM family m LEFT JOIN
(
  SELECT family_id, COUNT(*) kids_numb
    FROM student
   WHERE status = 1
   GROUP BY family_id
 ) s 
    ON m.family_id = s.family_id LEFT JOIN 
(
  SELECT family_id, SUM(amount) paid_amount
    FROM fee 
    GROUP BY family_id
) f
  ON m.family_id = f.family_id
 WHERE s.family_id IS NOT NULL

样本输出:

| FAMILY_ID | FAMILY_NAME | KIDS_NUMB | PAID_AMOUNT | |-----------|-------------|------------|----------- --| | 1 |黎巴嫩 | 1 | 200 | | 2 |拉沃伊 | 2 | 150 | | 3 |午睡 | 1 | 0 | | 4 |专业 | 3 | 300 |

这里是SQLFiddle演示


UPDATE2:添加总计

SELECT family_id, family_name, SUM(kids_numb) kids_numb, SUM(paid_amount) paid_amount
  FROM
(
  SELECT m.family_id, m.family_name, s.kids_numb, COALESCE(f.paid_amount, 0) paid_amount
    FROM family m LEFT JOIN
  (
    SELECT family_id, COUNT(*) kids_numb
      FROM student
     WHERE status = 1
     GROUP BY family_id
   ) s 
      ON m.family_id = s.family_id LEFT JOIN 
  (
    SELECT family_id, SUM(amount) paid_amount
      FROM fee 
      GROUP BY family_id
  ) f
    ON m.family_id = f.family_id
   WHERE s.family_id IS NOT NULL
) q
 GROUP BY family_id, family_name WITH ROLLUP
HAVING (family_id IS NOT NULL AND 
        family_name IS NOT NULL)
    OR (family_id IS NULL AND 
        family_name IS  NULL)

样本输出:

| FAMILY_ID | FAMILY_NAME | KIDS_NUMB | PAID_AMOUNT | |-----------|-------------|------------|----------- --| | 1 |黎巴嫩 | 1 | 200 | | 2 |拉沃伊 | 2 | 150 | | 3 |午睡 | 1 | 0 | | 4 |专业 | 3 | 300 | | (空) | (空) | 7 | 650|

MySQL GROUP BY 非标准扩展将允许您更改整个部分

 GROUP BY family_id, family_name WITH ROLLUP
HAVING (family_id IS NOT NULL AND 
        family_name IS NOT NULL)
    OR (family_id IS NULL AND 
        family_name IS  NULL)

只有

 GROUP BY family_id WITH ROLLUP

但是在family_name 列中的NULL 将有一个姓氏的值,而不是family_name 列的总行。

样本输出:

| FAMILY_ID | FAMILY_NAME | KIDS_NUMB | PAID_AMOUNT | |-----------|-------------|------------|----------- --| | 1 |黎巴嫩 | 1 | 200 | | 2 |拉沃伊 | 2 | 150 | | 3 |午睡 | 1 | 0 | | 4 |专业 | 3 | 300 | | (空) |专业 | 7 | 650|

这里是SQLFiddle演示

【讨论】:

  • 查看更新的答案。顺便说一句,您最好将 cmets 写入答案而不是您的问题。
  • 如果它不起作用,那么您很可能复制错了。您是否看过我提供的工作 sqlfiddle 示例?再次请让 cmets 我的回答,不要回答你的自己的问题。
  • 对不起cmets。是的,我总是先检查你的例子。我正在我的本地机器上进行测试。我什至从您的查询中复制/粘贴,但仍然只有小代码对我有用。也许我的 PHP 代码中有一些东西?我会找到的。但相信我,我对我所拥有的一切都很好。非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-21
  • 2015-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-09
相关资源
最近更新 更多