SQL SERVER 实现相同记录为空显示(多列去除重复值,相同的只显示一条数据)
sql server语句查询中碰到结果集有重复数据,需要把这个重复数据汇总成一条显示。其余则正常显示。
使用SQL内置函数 ROW_NUMBER() 加 PARTITION 完成
ROW_NUMBER() OVER ( PARTITION BY '相同数据字段' ORDER BY GETDATE() ) row
PARTITION BY和GROUP BY类似。
GROUP BY会影响行数,针对于所有字段进行一个聚合。
PARTITION BY则不会影响行数,用做于此处刚刚好。
例:查询出字段有A、B、C、D、E。其中A代表姓名、B代表年龄、C代码性别、D代表爱好、E代表喜欢游戏。
其中A、B、C,这三个字段中有重复字段,而D、E则无重复字段。
那么语句便可以这样写
SELECT *,ROW_NUMBER() OVER ( PARTITION BY A,B,C ORDER BY GETDATE() ) row FROM tab
这样你便会看到你的结果中row字段会依据A、B、C三个字段依据不同值分别做一个分组。
| A | B | C | D | E | row |
| 小明 | 18 | 1 | 篮球 | LOL | 1 |
| 小明 | 18 | 1 | 乒乓球 | DNF | 2 |
| 小黄 | 18 | 2 | 游泳 | LOL | 1 |
| 小黄 | 18 | 2 | 滑板 | QQ飞车 | 2 |
| 小黄 | 18 | 2 | 跑步 | 战地五 | 3 |
| 小孙 | 18 | 1 | 睡觉 | 剑网三 | 1 |
所以以上数据便是依据PARTITION BY分组所显示行号。
既然已经得到这样的数据,那么把相同的数据更改为空就很简单了。使用CASE WHEN便可以实现。
SELECT CASE WHEN row = 1 THEN T.A
ELSE ''
END A ,
CASE WHEN row = 1 THEN T.B
ELSE ''
END B ,
CASE WHEN row = 1 THEN T.C
ELSE ''
END C ,
T.D ,
T.E
FROM ( SELECT * ,
ROW_NUMBER() OVER ( PARTITION BY A, B, C ORDER BY GETDATE() ) row
FROM tab
) T
那么以上语句执行最终结果便是一下表格里的数据:
| A | B | C | D | E | row |
| 小明 | 18 | 1 | 篮球 | LOL | 1 |
| 乒乓球 | DNF | 2 | |||
| 小黄 | 18 | 2 | 游泳 | LOL | 1 |
| 滑板 | QQ飞车 | 2 | |||
| 跑步 | 战地五 | 3 | |||
| 小孙 | 18 | 1 | 睡觉 | 剑网三 | 1 |
这样一来就简介多了,SQL SERVER很多内置函数还是非常好用的。
最后放上一个测试临时表格供大家测试吧!
CREATE TABLE #tab
(
headerNo VARCHAR(10) ,
machineNO VARCHAR(10) ,
descrption NVARCHAR(20) ,
artNo VARCHAR(20) ,
qty INT ,
repartno VARCHAR(20) ,
repqty INT
)
插入数据
insert INTO #tab SELECT 'HD01','0101520',N'电池出问题','102020',2,'102020',2
insert INTO #tab SELECT 'HD01','0101520',N'电池出问题','101010',2,'202020',2
insert INTO #tab SELECT 'HD01','0101520',N'电池出问题','126888',2,'102020',2
insert INTO #tab SELECT 'HD02','01012221',N'D电机故障','102020',2,'102020',2
insert INTO #tab SELECT 'HD03','12312312',N'突然停机','102020',2,'102020',2
insert INTO #tab SELECT 'HD03','12312312',N'突然停机','102020',2,'102020',2
insert INTO #tab SELECT 'HD04','12312344',N'皮带松了','102020',2,'102020',2
语句查询执行
SELECT CASE WHEN row = 1 THEN headerNo
ELSE ''
END headerNo ,
CASE WHEN row = 1 THEN machineNO
ELSE ''
END machineNO ,
CASE WHEN row = 1 THEN descrption
ELSE ''
END descrption ,
artNo ,
qty ,
repartno ,
repqty
FROM ( SELECT * ,
ROW_NUMBER() OVER ( PARTITION BY headerNo, machineNO,
descrption ORDER BY GETDATE() ) row
FROM #tab
) M
以上测试SQL语句来自博客园以下老哥的文章,它的文章只编写了SQL语句供予测试。
我加以修改,做了一些理解性的分析。
https://www.cnblogs.com/panxuguang/p/5668520.html
后续更新
PARTITION BY简称分区函数,GROUP BY为聚合函数。
PARTITION BY的使用之处可以有很多,文章的上半部分查询出来的数据用于报表非常合适。
但用作于程序中就会显得比较复杂。
以此可以思考,既然 PARTITION BY是依据当前字段不同的字段做一个分组,不影响数据结构、数据行。
结合ROW_NUMBER对分组后的数据进行一个排序。这样就可以根据ROU_NUMBER后的字段进行数据查询。
同时,PARTITION BY 还可以在一个查询语句中针对于多个字段进行查询。但后续的PARTITION BY须携带上前一个字段。
比如上面例子中再增加一个字段,父母标识。L字段中,0代表自己,1代表母亲,2代表父亲。D和E就表示父母的爱好。
SELECT CASE WHEN row = 1 THEN T.A
ELSE ''
END A ,
CASE WHEN row = 1 THEN T.B
ELSE ''
END B ,
CASE WHEN row = 1 THEN T.C
ELSE ''
END C ,
CASE WHEN row2 = 1 THEN T.L
ELSE ''
END F,
T.D ,
T.E
FROM ( SELECT * ,
ROW_NUMBER() OVER ( PARTITION BY A, B, C ORDER BY GETDATE() ) row,
ROW_NUMBER() OVER ( PARTITION BY A, B, C, L ORDER BY GETDATE() ) row2
FROM tab
) T
这样除了第一次的依据A,B,C进行了一个内部分区排序,
随后第二次操作就会依据A,B,C为参照针对L的不同字段在做一个内部分区排序。数据就是下面的样式
| A | B | C | L | D | E |
| 小明 | 18 | 1 | 0 | 篮球 | LOL |
| 乒乓球 | DNF | ||||
| 2 | 篮球 | 吃鸡 | |||
| 跳伞 | 黎明杀机 | ||||
| 1 | 跳绳 | 和平精英 | |||
| 小黄 | 18 | 2 | 游泳 | LOL | |
| 滑板 | QQ飞车 | ||||
| 跑步 | 战地五 | ||||
| 小孙 | 18 | 1 | 睡觉 | 剑网三 |
通过PARTITON BY 分区排序之后,你还可以取以什么为条件了前三条,以什么字段为排序的第一条等等操作
SQL SERVER 实现相同记录为空显示(多列去除重复值,相同的只显示一条数据)的更多相关文章
- SQL Server 最小日志记录
SQL Server之所以记录事务日志,首要目的是为了把失败或取消的操作还原到最原始的状态,但是,并不是所有的操作都需要完全记录事务日志,比如,在一个空表上放置排他锁,把大量的数据插入到该空表中.即使 ...
- SQL Server 查询表的记录数(3种方法,推荐第一种)
http://blog.csdn.net/smahorse/article/details/8156483 --SQL Server 查询表的记录数 --one: 使用系统表. SELECT obje ...
- 【转】SQL Server 查询表的记录数(3种方法,推荐第一种)
--SQL Server 查询表的记录数 --one: 使用系统表. SELECT object_name (i.id) TableName, rows as RowCnt FROM sysindex ...
- sql server显示某一列中有重复值的行
sql server查询一张表 ,显示某一列中有重复值的行,可以这样写: Select * From 表名 where 列名 in(Select 列名 From Table group by 列名 h ...
- SQL SERVER 判断是否存在数据库、表、列、视图
SQL SERVER 判断是否存在数据库.表.列.视图 --1. 判断数据库是否存在 IF EXISTS (SELECT * FROM SYS.DATABASES WHERE NAME = '数据库名 ...
- img只显示图片一部分 或 css设置背景图片只显示图片指定区域
17:14 2016/3/22img只显示图片一部分 或 css设置背景图片只显示图片指定区域 background-position: 100% 56%; 设置背景图片显示图片的哪个坐标区域,图片左 ...
- sql server相邻表记录交换(单双两两交换)
在博客园的博问中看到了一个这样的提问:一个表中有id和name两个字段,id是连续非空不重复的,想要交换相邻表记录的name值(单双两两交换). 另外,如果最后的单独行没有对应的下一行匹配记录的话,就 ...
- SQL SERVER常用语法记录
用于记录SQL SERVER常用语法,以及内置函数. 以下语句包含: WITH 临时表语法 ROW_NUMBER()内置函数,我一般主要是用来分页.针对于查出来的所有数据做一个数字排序 分页的BETW ...
- SQL Server 2005中的分区表(二):如何添加、查询、修改分区表中的数据(转)
在创建完分区表后,可以向分区表中直接插入数据,而不用去管它这些数据放在哪个物理上的数据表中.接上篇文章,我们在创建好的分区表中插入几条数据 insert Sale ([Name],[SaleTime] ...
随机推荐
- PHP--date转成时间戳,time()获取的是秒数
date("Y-m-d H:i:s"); //如果存成datetime型在MYSQL中 必须用这种格式 实现功能:获取某个日期的时间戳,或获取某个时间的时间戳.strtotime ...
- 【Idea】实用插件列表
1.Translation : 翻译 2.CodeGlance:代码预览 3.Lombok:优雅编程插件 4.GenerateSerialVersionUID :自动生成序列化ID 5.CamelCa ...
- hdu4807枚举费用流
题意: 给你一个有向图,每条边上都有每一时刻的最大流量,有k个人在点0,他们要去点n-1,问你最晚到达的那个人最快要多久. 思路: 这个题目做了很多次,用过费用流,也用过最大流,结 ...
- SSM中事务的配置模板
Spring-tx.xml 配置思路: 1. 声明事务管理器DataSourceTransactionManager,并注入数据源dataSource属性 2.配置事务增强<tx:advice& ...
- 小技巧!CSS 提取图片主题色功能探索
本文将介绍一种利用 CSS 获取图片主题色的小技巧.一起看看~ 背景 起因是微信技术群里有个同学发问,有什么方法能够获取图片的主色呢?有一张图片,获取他的主色调: 利用获取到的这个颜色值,来实现类似这 ...
- Java项目中每一个类都可以有一个main方法
Java项目中每一个类都可以有一个main方法,但只有一个main方法会被执行,其他main方法可以对类进行单元测试. public class StaticTest { public static ...
- SE_Work1_阅读构建之法&项目管理实践
项目 内容 课程:北航-2020-春-软件工程 博客园班级博客 要求:阅读<构建之法>并回答问题 个人博客作业 我在这个课程的目标是 提升团队管理及合作能力,开发一项满意的工程项目 这个作 ...
- 痞子衡嵌入式:MCUBootUtility v3.3发布,可配合SBL项目使用
-- 痞子衡维护的NXP-MCUBootUtility工具距离上一个大版本(v3.0.0)发布过去4个多月了,期间痞子衡其实断断续续做个几个小版本更新,这一次痞子衡为大家带来了稳定版本v3.3.0,顺 ...
- stm32开发笔记(三):stm32系列的GPIO基本功能之输出驱动LED灯、输入按键KEY以及Demo
前言 stm32系列是最常用的单片机之一,不同的版本对应除了引脚.外设.频率.容量等'不同之外,其开发的方法是一样的. 本章讲解使用GPIO引脚功能驱动LED灯和接收Key按钮输入. STM ...
- Java 正则表达式实例操作
Regular Expression正则表达式,简称RegExp,常规通用的表达式,在多个开发语言中都有它的实现,可以通过正则表达式来快速的检索.匹配.查找.替换字符串中的文本. 简单实例 匹配网址 ...