mysql分组求和,并对和排序、取top n

面试时遇到的一个问题,当时我都把那个sql在纸上写出来了,面试官也没看我写得是什么,我自己也不敢确定,然后支支吾吾对面试官说没有写出来。现在回想起来,多么简单的一个sql,愧对我那些年写过的代码。

还有就是在面试时写算法或sql语句时,按着自己的想法写出来,不管自己确不确定,先给面试官看,没准面试官会给你屡思路,自己也会从中学习。

来看问题:

create table tb_user_finance (
  id bigint primary key auto_increment,
  uid bigint not null default 0 comment '用户id',
  money decimal(10, 2) not null default 0.00 comment '资金流水',
  type tinyint not null default 0 comment '1: 转账, 10: 提现, 20: 充值',
  created_at timestamp not null default current_timestamp,
  updated_at timestamp not null default current_timestamp on update current_timestamp,
  key ix_uid (uid)
) engine = innodb default charset=utf8 comment '用户资金流水表';

insert into tb_user_finance (uid, money, type) values(10, 20, 1);
insert into tb_user_finance (uid, money, type) values(10, 20, 1);
insert into tb_user_finance (uid, money, type) values(10, 20, 1);
insert into tb_user_finance (uid, money, type) values(10, 200, 1);

insert into tb_user_finance (uid, money, type) values(20, 10, 10);
insert into tb_user_finance (uid, money, type) values(30, 20, 20);
insert into tb_user_finance (uid, money, type) values(30, 10, 20);

insert into tb_user_finance (uid, money, type) values(31, 10, 20);
insert into tb_user_finance (uid, money, type) values(32, 20, 20);
insert into tb_user_finance (uid, money, type) values(33, 45, 20);
insert into tb_user_finance (uid, money, type) values(34, 100, 20);
insert into tb_user_finance (uid, money, type) values(35, 1000, 20);
insert into tb_user_finance (uid, money, type) values(36, 1090, 20);

有一个用户资金流水表(如上的sql代码),找出流水金额最多的前10个用户:

select uid, sum(money) as total from tb_user_finance group by uid order by total desc limit 10;

sql根本不难,多注意细节的积累吧!

参考:MySQL获取分组后的TOP 1和TOP N记录

### MySQL 数据库查询操作示例 #### 基本查询 为了获表中的所有记录,可以使用简单的 `SELECT` 语句。例如,假设有一个名为 `employees` 的表,则可以通过下面的 SQL 语句来检索该表内的所有数据: ```sql SELECT * FROM employees; ``` 当只需要特定列的信息时,可以在 `SELECT` 后面指定这些列的名字[^1]。 #### 使用 DISTINCT 关键词消除重复项 如果希望返回的结果集中不含有任何冗余的数据行,可利用 `DISTINCT` 来实现这一点。比如想要得到公司内部独一无二的工作职位列表,应该这样写: ```sql SELECT DISTINCT job_title FROM employees; ``` 这会确保每一个工作头衔只会出现一次[^2]。 #### 添加 WHERE 子句进行条件筛选 通过附加 `WHERE` 子句给查询提供额外的选择标准,从而精确控制所选出来的记录范围。考虑这样一个场景:找出工资超过80,000美元的所有员工姓名及其薪水数额: ```sql SELECT first_name, last_name, salary FROM employees WHERE salary > 80000; ``` 此命令仅显示满足设定阈值以上的雇员资料。 #### 排序结果集 ORDER BY 为了让最终输出按照某种顺序排列,可在查询结尾处追加 `ORDER BY` 子句。继续上面的例子,现在还希望能够按降序展示上述人员名单: ```sql SELECT first_name, last_name, salary FROM employees WHERE salary > 80000 ORDER BY salary DESC; ``` 这里的 `DESC` 表明是从高到低排序;如果不加上参数,默认情况下将是升序 (`ASC`) . #### 聚合函数的应用 对于统计分析来说,聚合函数是非常有用的工具之一。它们允许计算诸如总、平均数之类的数值型属性。举例而言,想知道整个部门成员薪资总额的话,可以用如下方式表达需求: ```sql SELECT SUM(salary) AS total_salary FROM employees; ``` 这段代码不仅执行了求和动作,而且借助别名机制让输出更易于理解. #### JOIN 操作关联多张表格 有时候单靠一张表无法完成复杂的业务逻辑处理,这时就需要把几张有关联性的表结合起来看。以订单管理客户信息为例,假设有两张分别存储着顾客详情(`customers`)以及他们下的定单(`orders`)的表,那么要找到某位具体客户的最近一笔交易日期就可以这样做: ```sql SELECT c.customer_id, o.order_date FROM customers c INNER JOIN orders o ON c.customer_id = o.customer_id WHERE c.first_name='John' AND c.last_name='Smith'; ``` 这里采用了内连接(inner join),意味着只有那些能在双方都找到匹配记录的情况才会被保留下来参与后续的操作. #### 子查询嵌套 某些复杂的需求可能涉及到先从某个集合里面挑出一部分符合条件的对象作为下一步骤的基础素材。这时候就轮到了子查询出场发挥作用了。设想一下这样的情况:寻找在过去一年里购买次数最多的产品类别。为此,首先要识别出活跃度最高的几位买家群体,然后再基于这些人再去考察其消费偏好分布状况: ```sql WITH top_buyers AS ( SELECT customer_id FROM purchases GROUP BY customer_id HAVING COUNT(*) >= ALL (SELECT COUNT(*) FROM purchases GROUP BY customer_id) ) SELECT p.category FROM products p JOIN purchases pu ON p.product_id=pu.product_id JOIN top_buyers tb ON pu.customer_id=tb.customer_id GROUP BY p.category ORDER BY COUNT(pu.purchase_id) DESC LIMIT 1; ``` 以上例子展示了如何构建一个带有窗口功能(CTE)结合多个层次化的子查询结构来进行深入挖掘的过程.
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值