 :SQL SERVER 实现相同记录为空显示(多列去除重复值,相同的只显示一条数据)
: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 分区排序之后,你还可以取以什么为条件了前三条,以什么字段为排序的第一条等等操作
点晴模切ERP更多信息:http://moqie.clicksun.cn,联系电话:4001861886
该文章在 2023/3/20 16:15:26 编辑过