记录SQL语句先排序再分组

此篇博客介绍了如何使用SQL语句从stu表中按时间顺序排列并按姓名分组,展示了数据筛选和聚合的基本操作。
基本表结构

在这里插入图片描述

/*
 Navicat Premium Data Transfer

 Source Server         : mylife
 Source Server Type    : MySQL
 Source Server Version : 50528
 Source Host           : localhost:3306
 Source Schema         : test

 Target Server Type    : MySQL
 Target Server Version : 50528
 File Encoding         : 65001

 Date: 30/07/2021 10:31:25
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for stu
-- ----------------------------
DROP TABLE IF EXISTS `stu`;
CREATE TABLE `stu`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `pass` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `time` datetime NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

-- ----------------------------
-- Records of stu
-- ----------------------------
INSERT INTO `stu` VALUES (1, 'zs', '123', '2021-07-30 09:10:51');
INSERT INTO `stu` VALUES (2, 'ls', '123', '2021-07-13 09:10:58');
INSERT INTO `stu` VALUES (3, 'zs', '123', '2020-06-30 09:11:02');
INSERT INTO `stu` VALUES (4, 'ls', 're', '2021-05-26 09:11:09');

SET FOREIGN_KEY_CHECKS = 1;

SQL语句
select *from 
(select *from stu order by time)
as new_tbl 
group by name;

在这里插入图片描述

在 Oracle SQL 中实现分组排序,可以使用 `ROW_NUMBER()`、`RANK()` 或 `DENSE_RANK()` 等窗口函数,并结合 `PARTITION BY` 子句来对数据进行分组排序。以下是一些常见的写法示例: ### 使用 `ROW_NUMBER()` 实现分组排序 通过 `ROW_NUMBER()` 函数,可以在每个分组内生成唯一的序号,常用于需要唯一排名的场景。例如,按 `contract_code` 分组并按 `gu_id` 排序: ```sql SELECT t.contract_code, t.gu_id, ROW_NUMBER() OVER (PARTITION BY t.contract_code ORDER BY t.gu_id) AS rn, t.* FROM v_swap_confirmation t ORDER BY t.contract_code; ``` 该语句中,`PARTITION BY t.contract_code` 表示按 `contract_code` 进行分组,`ORDER BY t.gu_id` 表示在每组内按 `gu_id` 排序,然后为每行生成一个唯一的序号 [^2]。 ### 使用 `RANK()` 实现分组排序 如果希望在遇到相同值时赋予相同的排名,则可以使用 `RANK()` 函数。例如,按 `contract_code` 分组并按 `gu_id` 排序,同时允许重复排名: ```sql SELECT t.contract_code, t.gu_id, RANK() OVER (PARTITION BY t.contract_code ORDER BY t.gu_id) AS rank, t.* FROM v_swap_confirmation t ORDER BY t.contract_code; ``` 这种方式适用于需要处理并列排名的场景,如竞赛成绩排名等 [^2]。 ### 使用 `DENSE_RANK()` 实现更紧凑的分组排序 与 `RANK()` 不同,`DENSE_RANK()` 在跳过重复排名时不会留空位。例如: ```sql SELECT t.contract_code, t.gu_id, DENSE_RANK() OVER (PARTITION BY t.contract_code ORDER BY t.gu_id) AS dense_rank, t.* FROM v_swap_confirmation t ORDER BY t.contract_code; ``` 此方法适合要求排名连续且不出现跳跃的场景 [^2]。 ### 分组后获取特定行(如每组第一条) 如果需要获取每组中的第一条记录,可以结合子查询和 `ROW_NUMBER()` 函数: ```sql SELECT * FROM ( SELECT t.contract_code, t.gu_id, ROW_NUMBER() OVER (PARTITION BY t.contract_code ORDER BY t.gu_id) AS rn FROM v_swap_confirmation t ) ranked_data WHERE rn = 1; ``` 此方法适用于提取每组中具有最小或最大值的记录 [^4]。 ### 分组后组内排序并获取下一行数据 还可以使用 `LEAD()` 或 `LAG()` 函数实现在组内排序后访问前后行的数据。例如,获取当前行之后的 `stepid`: ```sql SELECT caseid, stepid, actiondate, LEAD(stepid) OVER (PARTITION BY caseid ORDER BY actiondate) AS nextstepid FROM v_swap_confirmation; ``` 此方法适用于分析时间序列或流程步骤之间的关系 [^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐 昊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值