محمد کمائی - Telegram : @komayi
محمد کمائی - Telegram : @komayi
خواندن ۲ دقیقه·۳ سال پیش

حذف رکوردهای تکراری در اس کیو ال - Delete Duplicate rows in SQL Server

فرض کنید در جدولی رکوردهایی شبیه به هم ایجاد شده و باعث کندی در سیستم شده مخصوصا جداول پایه سیستم که تعداد کوئری روی اون زیاده و در حجم توکن و کوکی هم تاثیر میزاره.

مثلا جدول AspNetRoleClaims که میگه هر role به چه اکشنهایی دسترسی داره. ستونهای جدول AspNetRoleClaims :

Id, ClaimType, ClaimValue, RoleId

که ClaimType اسم controller و ClaimValue اسم action هست و هر رکورد میگه که این رل به این controller و این action دسترسی داره.

اگه رکوردهایی تکراری داشته باشیم یعنی با Id های متفاوت ولی ClaimType, ClaimValue, RoleId های یکسان. چه جوری رکوردهای تکراری رو حذف کنیم؟

اولا برای اینکه بدونیم رکورد تکراری داریم یا نه میشه جواب این دو select رو با هم مقایسه کرد:

select ClaimType,ClaimValue,RoleId from AspNetRoleClaims select distinct ClaimType,ClaimValue,RoleId from AspNetRoleClaims

که فرقشون در distinct هست ، اگر این سه فیلد ClaimType, ClaimValue, RoleId تکرار شده باشن تعداد جواب این دو سلکت متفاوت هست یعنی رکورد تکراری داریم و اگر تعداد جواب این دو سلکت مساوی بود یعنی رکورد تکراری نداریم.

حالا اگر رکورد تکراری داشتیم چه کار کنیم؟

یه راه حل ساده اینه که با ROW_NUMBER تعداد هر رکورد رو مشخص کنیم و بریزیم در یک temp table :

SELECT Id, ClaimType, ClaimValue, RoleId, ROW_NUMBER() OVER ( PARTITION BY ClaimType,ClaimValue,RoleId ORDER BY ClaimType,ClaimValue,RoleId) row_num into #temp FROM AspNetRoleClaims

دقت کنید که در جلوی PARTITION BY ستون Id رو نمیاریم چون Id کلید اصلی جدول هست و unique هست و اگر بیاد نتیجه select میشه : همه رکوردها 1 بار تکرار شدن. پس محتوای temp# میشه همه رکوردها و همه ستونها به علاوه ستون row_num که میگه این رکورد چند بار در این جدول اومده.

خب حالا کافیه رکوردهایی از جدول AspNetRoleClaims رو delete کنیم که در temp# ستون row_num شون بیشتر از 1 هست ، ارتباط رکوردهای این دو جدول هم از طریق Id انجام میدیم.

پس با این delete رکوردهای تکراری AspNetRoleClaims رو حذف میکنیم:

delete AspNetRoleClaims where Id in(select Id from #temp where row_num>1)

در نهایت هم temp# رو drop میکنیم :

drop table #temp
sqlserverdelete
C# , .net core & angular & blazor , sql server
شاید از این پست‌ها خوشتان بیاید