:SQL SERVER 實現(xiàn)相同記錄為空顯示(多列去除重復(fù)值,相同的只顯示一條數(shù)據(jù)) sql server語句查詢中碰到結(jié)果集有重復(fù)數(shù)據(jù),需要把這個重復(fù)數(shù)據(jù)匯總成一條顯示。其余則正常顯示。
使用SQL內(nèi)置函數(shù) ROW_NUMBER() 加 PARTITION 完成
ROW_NUMBER() OVER ( PARTITION BY '相同數(shù)據(jù)字段' ORDER BY GETDATE() ) row
PARTITION BY和GROUP BY類似。
GROUP BY會影響行數(shù),針對于所有字段進(jìn)行一個聚合。
PARTITION BY則不會影響行數(shù),用做于此處剛剛好。
例:查詢出字段有A、B、C、D、E。其中A代表姓名、B代表年齡、C代碼性別、D代表愛好、E代表喜歡游戲。
其中A、B、C,這三個字段中有重復(fù)字段,而D、E則無重復(fù)字段。
那么語句便可以這樣寫
select *,ROW_NUMBER() OVER ( PARTITION BY A,B,C ORDER BY GETDATE() ) row from tab
這樣你便會看到你的結(jié)果中row字段會依據(jù)A、B、C三個字段依據(jù)不同值分別做一個分組。
A | B | C | D | E | row |
小明 | 18 | 1 | 籃球 | LOL | 1 |
小明 | 18 | 1 | 乒乓球 | DNF | 2 |
小黃 | 18 | 2 | 游泳 | LOL | 1 |
小黃 | 18 | 2 | 滑板 | QQ飛車 | 2 |
小黃 | 18 | 2 | 跑步 | 戰(zhàn)地五 | 3 |
小孫 | 18 | 1 | 睡覺 | 劍網(wǎng)三 | 1 |
所以以上數(shù)據(jù)便是依據(jù)PARTITION BY分組所顯示行號。
既然已經(jīng)得到這樣的數(shù)據(jù),那么把相同的數(shù)據(jù)更改為空就很簡單了。使用CASE WHEN便可以實現(xiàn)。
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
那么以上語句執(zhí)行最終結(jié)果便是一下表格里的數(shù)據(jù):
A | B | C | D | E | row |
小明 | 18 | 1 | 籃球 | LOL | 1 |
|
|
| 乒乓球 | DNF | 2 |
小黃 | 18 | 2 | 游泳 | LOL | 1 |
|
|
| 滑板 | QQ飛車 | 2 |
|
|
| 跑步 | 戰(zhàn)地五 | 3 |
小孫 | 18 | 1 | 睡覺 | 劍網(wǎng)三 | 1 |
這樣一來就簡介多了,SQL SERVER很多內(nèi)置函數(shù)還是非常好用的。
最后放上一個測試臨時表格供大家測試吧!
create TABLE #tab
(
headerNo VARCHAR(10) ,
machineNO VARCHAR(10) ,
descrption NVARCHAR(20) ,
artNo VARCHAR(20) ,
qty INT ,
repartno VARCHAR(20) ,
repqty INT
)
插入數(shù)據(jù)
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電機(jī)故障','102020',2,'102020',2
insert INTO #tab select 'HD03','12312312',N'突然停機(jī)','102020',2,'102020',2
insert INTO #tab select 'HD03','12312312',N'突然停機(jī)','102020',2,'102020',2
insert INTO #tab select 'HD04','12312344',N'皮帶松了','102020',2,'102020',2
語句查詢執(zhí)行
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
后續(xù)更新
PARTITION BY簡稱分區(qū)函數(shù),GROUP BY為聚合函數(shù)。
PARTITION BY的使用之處可以有很多,文章的上半部分查詢出來的數(shù)據(jù)用于報表非常合適。
但用作于程序中就會顯得比較復(fù)雜。
以此可以思考,既然 PARTITION BY是依據(jù)當(dāng)前字段不同的字段做一個分組,不影響數(shù)據(jù)結(jié)構(gòu)、數(shù)據(jù)行。
結(jié)合ROW_NUMBER對分組后的數(shù)據(jù)進(jìn)行一個排序。這樣就可以根據(jù)ROU_NUMBER后的字段進(jìn)行數(shù)據(jù)查詢。
同時,PARTITION BY 還可以在一個查詢語句中針對于多個字段進(jìn)行查詢。但后續(xù)的PARTITION BY須攜帶上前一個字段。
比如上面例子中再增加一個字段,父母標(biāo)識。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
這樣除了第一次的依據(jù)A,B,C進(jìn)行了一個內(nèi)部分區(qū)排序,
隨后第二次操作就會依據(jù)A,B,C為參照針對L的不同字段在做一個內(nèi)部分區(qū)排序。數(shù)據(jù)就是下面的樣式
A | B | C | L | D | E |
小明 | 18 | 1 | 0 | 籃球 | LOL |
|
|
|
| 乒乓球 | DNF |
|
|
| 2 | 籃球 | 吃雞 |
|
|
|
| 跳傘 | 黎明殺機(jī) |
|
|
| 1 | 跳繩 | 和平精英 |
小黃 | 18 | 2 |
| 游泳 | LOL |
|
|
|
| 滑板 | QQ飛車 |
|
|
|
| 跑步 | 戰(zhàn)地五 |
小孫 | 18 | 1 |
| 睡覺 | 劍網(wǎng)三 |
通過PARTITON BY 分區(qū)排序之后,你還可以取以什么為條件了前三條,以什么字段為排序的第一條等等操作
點晴模切ERP更多信息:http://moqie.clicksun.cn,聯(lián)系電話:4001861886
該文章在 2023/3/20 16:15:26 編輯過