巧妙利用PARTITION分组排名递增特性解决合并连续相同数据行

 更新时间:2014年08月07日 16:51:45   投稿:hebedich  
这篇文章主要介绍了巧妙利用PARTITION分组排名递增特性解决合并连续相同数据行,需要的朋友可以参考下

问题提出

先造一些测试数据以说明题目:

DECLARE @TestData TABLE(ID INT,Col1 VARCHAR(20),Col2 VARCHAR(20)) 
INSERT INTO @TestData(ID,Col1,Col2) 
SELECT 1,'New','Approved' UNION ALL 
SELECT 2,'Approved','Commited' UNION ALL 
SELECT 3,'Commited','In Progress' UNION ALL 
SELECT 4,'New','Approved' UNION ALL 
SELECT 5,'New','Approved' UNION ALL 
SELECT 6,'New','Approved' UNION ALL 
SELECT 7,'Approved','Removed' 
SELECT * FROM @TestData

数据说明,ID列连续自增,列1和列2都是TFS中PBI的状态记录,就是从什么变更到什么,如新建到批准,批准到提交神马的

现在要求连续且相同的状态变更记录合并,不连续或者不同的状态变更保留,例如:

以上图为例,ID为1,4,5,6的记录都是从New到Approved状态,但是记录1与记录4、5、6不相邻,或者说不连续,那么就要分成两组,

记录1一组,记录4、5、6一组,其它记录因为状态变更不相同所以全部保留,最后的查询结果应该长成下图这个样子:

继续之前你可以先自己试下,这可能会带来新的解题思路,

解题思路

该问题的关键在于GROUP BY会把记录1、4、5、6合并在一起,而这不符合要求,仅需要合并4、5、6,源表里没有这样一个字段可以将记录1与记录4、5、6区分开来,这是解题的关键

这里可以利用RANK函数配合使用PARTITION关键字,首先把1456分到一组去,同时产生一个组内排名的新字段R,这个排名R很关键,后边会用到,见下图:

RANK函数不了解的点这里

RANK函数以Col1 + Col2为分组条件,这样分成了四组,分别是New-Approved、Approved-Commited、Commited-In Progress、Approved-Removed

在New-Approved组内,记录1、4、5、6分别排名1、2、3、4;其它组内仅一条记录,在其组内排名均为1

现在制造了一个R字段,R字段标识了每条记录在其组内的排名,排名自1开始递增,

源表内ID自增,组内排名R递增,这就是解题的关键,

当连续相同的记录出现时,其ID与其排名R在同时递增,则其差值是相同的,拿到这个差值就可以很容易解决题目了,看下图:

记录4、5、6相同且连续出现,其ID与其排名在同时增长,其差值则保持不变,这里使用Col1 + Col2 + Gap作为分组条件即可将记录4、5、6合并,再取个最小ID出来,问题解决,完整脚本如下:

可是如果ID不连续时怎么办呢?这个不难,参考[MSSQL]ROW_NUMBER函数

相关文章

  • SQL 尚未定义空闲 CPU 条件 - OnIdle 作业计划将不起任何作用

    SQL 尚未定义空闲 CPU 条件 - OnIdle 作业计划将不起任何作用

    今天在配置sql server 代理服务器的计划任务的时候发现了日志中提示这个SQL 尚未定义空闲 CPU 条件 - OnIdle 作业计划将不起任何作用信息导致无法执行计划任务,那么可以按照下面的方法解决即可
    2021-06-06
  • 使用row_number()实现分页实例

    使用row_number()实现分页实例

    或许大家不知道,其实使用row_number()是可以实现分页的,下面有个不错的示例,大家可以尝试操作下
    2013-11-11
  • 简单判断MSSQL数据库版本(2000或者2005)

    简单判断MSSQL数据库版本(2000或者2005)

    这篇文章主要介绍了简单判断MSSQL数据库版本(2000或者2005),需要的朋友可以参考下
    2015-01-01
  • MSSQL经典语句

    MSSQL经典语句

    MSSQL经典语句...
    2006-10-10
  • 在SQL SERVER中导致索引查找变成索引扫描的问题分析

    在SQL SERVER中导致索引查找变成索引扫描的问题分析

    SQL Server 中什么情况会导致其执行计划从索引查找(Index Seek)变成索引扫描(Index Scan)呢? 下面从几个方面结合上下文具体场景做了下测试、总结、归纳。需要的朋友可以参考下本文
    2015-09-09
  • 异步的SQL数据库封装详解

    异步的SQL数据库封装详解

    一直在寻找一种简单有效的库,它能在简化数据库相关的编程的同时提供一种异步的方法来预防死锁。使用这个库,你可以轻松地连接到任何SQL-Server数据库,执行任何存储过程或 T-SQL 查询,并异步地接收查询结果。这个库采用C#开发,没有其他外部依赖。
    2015-09-09
  • SQLServer更改sa用户名的方法

    SQLServer更改sa用户名的方法

    SQLServer更改sa用户名的方法,需要的朋友可以参考下。
    2010-11-11
  • 为数据库生成某个字段充填随机数的存储过程

    为数据库生成某个字段充填随机数的存储过程

    为数据库生成某个字段充填随机数
    2010-05-05
  • SQL server数据库日志文件收缩操作方法

    SQL server数据库日志文件收缩操作方法

    日常使用数据库可能存在日志每天增长10G或以上,太恐怖了!数据量过大导致服务器卡死,内存溢出,执行Sql过慢等问题,这篇文章主要给大家介绍了关于SQL server数据库日志文件收缩操作的相关资料,需要的朋友可以参考下
    2024-02-02
  • SQL Server2012在开发中的一些新特性

    SQL Server2012在开发中的一些新特性

    SQL Server 2012已经发布一段时间了,最近在新的机器上安装了最新的SQL Server 2012 SP1,体检下感觉良好。官方给出了一大堆SQL2012相对于SQL2008R2的新特性,但是大多数对于普通开发人员来说都是浮云,根本用不到,下面就说说一些对于开发人员来说比较有用的新特性。
    2013-04-04

最新评论