دور زدن محدودیت Row_Number 

در آموزش window function و توابع رتبه بندی دیدیم که تابع Row_Number به ازای هر کدام از رکوردهای خروجی، یک شماره ردیف اختصاص می دهد. فرمت کلی این تابع به صورت زیر است:

ROW_NUMBER ( ) 
    OVER ( [ PARTITION BY value_expression , ... [ n ] ] order_by_clause )

همانطور که مشخص است نوشتن دستور order by در تابع Row_Number الزامی است. به عبارتی دیگر در صورت طراحی کوئری و استفاده از تابع Row_Number بدون مرتب سازی یک فیلد در عبارت OVER با خطای زیر مواجه خواهیم شد:

                                                             Msg 4112, Level 15, State 1
The function 'ROW_NUMBER' must have an OVER clause with ORDER BY

به عنوان مثال اگر جدول Employees را با رکوردهای فرضی، به صورت زیر داشته باشیم:

--Employees ایجاد جدول   
CREATE TABLE [dbo].[Employees](
	[NatinalCode] [char](10),
	[Name] [nvarchar](50) ,
	[Family] [nvarchar](50) ,
	[JobGroup] [char](1),
	[Salary] [numeric](3,1) 
) 
GO
--درج مقادیر تستی در جدول
insert into [Employees] Values('1199800001',N'محسن',N'بندامیر','A',8),('1199800002',N'غلامرضا',N'محمدی','A',7.5)
,('1199800003',N'علیرضا',N'خورسندی','A' ,7.8 ),('1199800004',N'حسین',N'نوربخش', 'B',6 ),('1199800005',N'آرش',N'کمالی', 'B', 6.5)
,('1199800006',N'نرگس',N'سلیمانی', 'B', 6.8),('1199800007',N'شیوا',N'نادری','C' ,4.8 ),('1199800008',N'نجمه',N'قاسمی', 'C',4.6 ),
('1199800009',N'محمد',N'میرزاده', 'C', 4.3),('1199800010',N'ناصر',N'ندیمی','C',4 )

کوئری زیر را جهت اختصاص دادن شماره ردیف به رکوردهای خروجی اجرا می کنیم:

window-function-rownumber-error

دلیل ایجاد خطای بالا، مرتب نکردن رکوردها در عبارت ()OVER است. دقت کنید حتی با وجود ایندکس کلاستر در جدول، بازهم نوشتن دستور order by و مرتب سازی بر اساس یک فیلد الزامی است. و اما روش دور زدن این محدودیت Row_Number به صورت زیر است:

row-number-bypassing-the-limit

 

در کوئری بالا به جای استفاده از select 100 می توانیم از  SELECT 1, SELECT ‘A’, SELECT NULL و غیره نیز استفاده کنیم.