vlambda博客
学习文章列表

MySql场景题、GROUPBY分组规则


  • 一、问题

  • 二、结论证明


一、问题


思考一下假如你有一个这样的需求
有一张账单表(bill_detail),一张开票表(open_invoice) 每一个用户有三种费用类型,分别是水费、污水费、违约金。(分别对应cost_type = 01、02、03) 现在要查询每个用户的欠费总额,和是否开票。(注:只有水费可以开票,其它的不需要)


账单表(bill_detail)

CREATE TABLE `bill_detail` (
 `id` VARCHAR(50NOT NULL COMMENT 'id',
   `cost_type` VARCHAR(2NOT NULL COMMENT '费用类型 01 水费、02 污水费、03 违约金',
 `amount_money` FLOAT(10,2NOT NULL COMMENT '欠费金额',
 `user_name` VARCHAR(20)  NOT NULL COMMENT '用户名',
  PRIMARY KEY (`id`USING BTREE
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='账单明细表';

开票表(open_invoice)

CREATE TABLE `open_invoice` (
  `id` VARCHAR(50NOT NULL COMMENT 'id',
   `bill_detail_id` VARCHAR(50NOT NULL COMMENT '账单明细id',
 `open_invoice_status` INT(1NOT NULL COMMENT '开票状态(1 已开票, 0 未开票)',
  PRIMARY KEY (`id`USING BTREE
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='开票表';



方法一

我们知道group by是取分组后的第一条数据,所以我们只需要把bill_detail表进行排序,这样每一组(用户名分组)数据,费用类型为 01就是第一个了

SELECT
 sum(amount_money) money,
 invoice.open_invoice_status
FROM
 (SELECT * FROM bill_detail ORDER BY cost_type ASC) bill 
 LEFT JOIN open_invoice invoice ON bill.id = invoice.bill_detail_id
GROUP BY bill.user_name

方法二

SELECT
 sum(amount_money) money,
 invoice.open_invoice_status
FROM
 bill_detail bill 
 LEFT JOIN open_invoice invoice ON bill.id = invoice.bill_detail_id
GROUP BY bill.user_name

分组(group by)后,会选择第一条数据,连接查询会改变原本的查询顺序。(ON后面的字段有值的排在前面,null在后面)


因为我们题目说了,只有水费为01的才会开票,所以连接查询后01这条数据一定会是第一个,无需先排序。



二、结论证明


有一张用户表(user),和一张女朋友表(girl_friend) 我们要查询出来每个人的id、用户名、女朋友名称
注:我们知道不是每一个人都有女朋友的

用户表(user)

CREATE TABLE `user` (
  `id` varchar(50NOT NULL COMMENT 'id',
  `user_name` varchar(20NOT NULL COMMENT '用户名',
  PRIMARY KEY (`id`USING BTREE
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户';

女朋友表(girl_friend)

CREATE TABLE `girl_friend` (
  `id` varchar(50NOT NULL COMMENT 'id',
  `user_id` varchar(20NOT NULL COMMENT '所属用户',
  `girl_name` varchar(20NOT NULL COMMENT '女朋友名',
  PRIMARY KEY (`id`USING BTREE
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='女朋友表';

查询sql

SELECT
 user.id,
 user.user_name,
 girl.girl_name
FROM user 
LEFT JOIN girl_friend girl ON user.id = girl.user_id

实验一

当我们的表数据如下:

id user_name
1 张三
2 李四
3 王五

id user_id girl_name
1 1 芙蓉

查询结果如下:

id user_name girl_name
1 张三 芙蓉
2 李四
3 王五

实验二


用户表不变,女朋友表数据如下

id user_id girl_name
1 2 大乔
1 2 小乔

查询结果如下:

id user_name girl_name
2 李四 大乔
3 王五 小乔
1 张三