經常遇到這樣的問題,相同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分區...