(sql server)sql 分組取top1


  經常遇到這樣的問題,相同ID的數據有多筆,但是只能任取其中一筆,下面是我的一個思考過程和學習過程。雖然比較基礎和簡單,但是總會有人不知道,也可以學習一下。

1:建表和初始化數據

create table TestTop
(
ID nvarchar(10), 
Name nvarchar(10),
Name_en nvarchar(10),
NoOne char(5),
NoTwo char(5),
NoThree char(5)
)
insert into TestTop values('I00001',N'測試1','abc','00001','00002','00003')
insert into TestTop values('I00001',N'測試1','abc','00001','00002','00003')
insert into TestTop values('I00001',N'測試2','bca','00002','00002','00003')
insert into TestTop values('I00001',N'測試3','aaa','00003','00001','00003')

insert into TestTop values('I00002',N'2測試1','gfg','00001','05002','09003')
insert into TestTop values('I00002',N'2測試2','dd','0022','00002','00003')

2:首先想到的肯定是group by ,但是group by 后面的欄位必須是聚合函數,如果用max或min,每個欄位取都不一定是同一筆數據的信息,這樣就有錯誤

select * from TestTop
select ID,max(Name)Name,max(Name_en)Name_en,max(NoOne)NoOne,max(NoTwo)NoTwo,max(NoThree)NoThree
from TestTop group by ID

3:本着先思考再找答案的思想,我想了一下,想到了一個很笨的辦法,如果我每個ID都排序取top1,那么top1的數據是固定的,這樣可以取到完整的一條,這樣是可以實現的。

但是還是有一個問題,如果有2條數據一模一樣,那這樣還要distinct一下。這個方法有個bug,如果有欄位為null,等於的時候就會出問題。

select * from TestTop
select distinct ID,Name,Name_en,NoOne,NoTwo,NoThree from TestTop TT
where TT.Name=(select top 1 Name from TestTop where ID=TT.ID order by ID,Name,Name_en,NoOne,NoTwo,NoThree asc)
and TT.Name_en=(select top 1 Name_en from TestTop where ID=TT.ID order by ID,Name,Name_en,NoOne,NoTwo,NoThree asc)
and TT.NoOne=(select top 1 NoOne from TestTop where ID=TT.ID order by ID,Name,Name_en,NoOne,NoTwo,NoThree asc)
and TT.NoTwo=(select top 1 NoTwo from TestTop where ID=TT.ID order by ID,Name,Name_en,NoOne,NoTwo,NoThree asc)
and TT.NoThree=(select top 1 NoThree from TestTop where ID=TT.ID order by ID,Name,Name_en,NoOne,NoTwo,NoThree asc)

4:剛那個方法雖然可以實現,但是如果欄位很多,那要寫的where條件就太多了,這時我就在網上查詢了一下,發現了一個好用的辦法。

row_number 方法配合partition by 分組編號,再取編號為1的就可以實現了。

partition可以分區,為每個ID編號,ID切換后重新開始編號,這個方法以前還沒見過,算是學習了。

select * from TestTop
select ROW_NUMBER() over(partition by ID order by ID) pid, * into #temp from TestTop
select * from #temp
select ID,Name,Name_en,NoOne,NoTwo,NoThree from #temp where pid=1
drop table #temp

 其實就些就是認識了partition分區...

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM