مثالهای عملی مستقل و قابل اجرا
مثال 1: محاسبه میانه کل داده
صدک 0.5 با PERCENTILE_DISC میانه موجود در داده را میسازد.
WITH D AS (SELECT Value FROM (VALUES (10),(20),(30),(40))V(Value))
SELECT DISTINCT PERCENTILE_DISC(0.5) WITHIN GROUP(ORDER BY Value) OVER() AS Median FROM D;
| تابع | میانه |
|---|
| PERCENTILE_DISC | 20 |
نکته کاربردی: DISTINCT فقط تکرار مقدار پنجرهای در خروجی نمایشی را حذف میکند؛ محاسبه روی همه ردیفها انجام شده است.
مثال 2: صدک نودم زمان پاسخ
در پایش SLA، صدک 0.9 تجربه کاربران کند را بهتر از میانگین نشان میدهد.
WITH R AS (SELECT Ms FROM (VALUES (80),(90),(100),(120),(500))V(Ms))
SELECT DISTINCT PERCENTILE_DISC(0.9) WITHIN GROUP(ORDER BY Ms) OVER() AS P90 FROM R;
نکته کاربردی: در گزارش SLA تعداد نمونه، بازه زمانی و سیاست حذف Outlier را کنار صدک ثبت کنید.
مثال 3: محاسبه میانه برای هر واحد
OVER(PARTITION BY) صدک را جداگانه برای هر دپارتمان محاسبه میکند.
WITH S AS (SELECT * FROM (VALUES (N'فروش',10),(N'فروش',30),(N'فنی',20),(N'فنی',40))V(Dept,Value))
SELECT DISTINCT Dept,PERCENTILE_DISC(0.5) WITHIN GROUP(ORDER BY Value) OVER(PARTITION BY Dept) AS Median FROM S;
نکته کاربردی: اندازه پارتیشن را نیز گزارش کنید؛ صدک گروه کوچک عدمقطعیت بیشتری دارد.
مثال 4: محاسبه چند صدک در یک Query
صدکهای 25، 50 و 75 نمای فشردهای از توزیع میسازند.
WITH D AS (SELECT Value FROM (VALUES (10),(20),(30),(40),(50))V(Value))
SELECT DISTINCT
PERCENTILE_DISC(0.25) WITHIN GROUP(ORDER BY Value) OVER() AS P25,
PERCENTILE_DISC(0.50) WITHIN GROUP(ORDER BY Value) OVER() AS P50,
PERCENTILE_DISC(0.75) WITHIN GROUP(ORDER BY Value) OVER() AS P75
FROM D;
نکته کاربردی: مشخصات پنجره یکسان به Optimizer امکان اشتراک برخی عملیات را میدهد؛ طرح اجرا را بررسی کنید.
مثال 5: فیلتر براساس آستانه صدکی
ابتدا آستانه در CTE محاسبه و سپس ردیفهای بزرگتر یا مساوی آن انتخاب میشوند.
WITH D AS (SELECT * FROM (VALUES (1,10),(2,20),(3,30),(4,100))V(Id,Value)),
W AS (SELECT *,PERCENTILE_DISC(0.75) WITHIN GROUP(ORDER BY Value) OVER() AS P75 FROM D)
SELECT Id,Value,P75 FROM W WHERE Value>=P75 ORDER BY Value;
نکته کاربردی: محل فیلتر مهم است؛ اگر پیش از محاسبه صدک داده حذف شود، خود آستانه نیز تغییر میکند.
مثال 6: رفتار NULL
توابع صدکی NULLهای عبارت مرتبسازی را نادیده میگیرند، اما تعداد داده معتبر باید کنترل شود.
WITH D AS (SELECT Value FROM (VALUES (CAST(NULL AS int)),(10),(20),(30))V(Value))
SELECT COUNT(Value) AS ValidCount,MAX(P50) AS P50
FROM (SELECT Value,PERCENTILE_DISC(0.5) WITHIN GROUP(ORDER BY Value) OVER() AS P50 FROM D)X;
نکته کاربردی: اگر همه مقادیر NULL باشند، نتیجه صدک NULL است؛ این حالت را در داشبورد از صفر متمایز کنید.
مثال 7: تفاوت پیوسته و گسسته
اجرای هر دو تابع روی داده زوج نشان میدهد درونیابی با انتخاب مقدار واقعی چه تفاوتی دارد.
WITH D AS (SELECT Value FROM (VALUES (10),(20),(30),(40))V(Value))
SELECT DISTINCT
PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY Value) OVER() AS ContinuousMedian,
PERCENTILE_DISC(0.5) WITHIN GROUP(ORDER BY Value) OVER() AS DiscreteMedian
FROM D;
نکته کاربردی: برای گزارش قیمت یا سطح خدمت که باید مقدار واقعی باشد گسسته مناسب است؛ برای تحلیل آماری، پیوسته رایجتر است.
مثال 8: صدک حقوق در گزارش سازمانی
این سناریو آستانه حقوق را برای هر JobLevel استخراج میکند و مقدار را کنار هر کارمند نگه میدارد.
WITH E AS (SELECT * FROM (VALUES (N'کارشناس',40),(N'کارشناس',50),(N'کارشناس',70),(N'مدیر',90),(N'مدیر',120))V(LevelName,Salary))
SELECT LevelName,Salary,PERCENTILE_DISC(0.5) WITHIN GROUP(ORDER BY Salary) OVER(PARTITION BY LevelName) AS LevelMedian
FROM E ORDER BY LevelName,Salary;
| سطح | حقوق | میانه سطح |
|---|
| کارشناس | 50 | 50 |
نکته کاربردی: دسترسی به داده حقوق باید کنترل شود و خروجی گروههای کوچک برای حفظ حریم خصوصی محدود گردد.
مثال 9: اصلاح محاسبه میانگین بهجای صدک
AVG مرکز حسابی است و در داده دارای مقدار دورافتاده جایگزین میانه یا P90 نیست.
WITH D AS (SELECT Value FROM (VALUES (10),(11),(12),(1000))V(Value))
SELECT DISTINCT AVG(1.0*Value) OVER() AS AverageValue,
PERCENTILE_DISC(0.5) WITHIN GROUP(ORDER BY Value) OVER() AS MedianValue
FROM D;
نکته کاربردی: انتخاب شاخص باید از سؤال تحلیلی بیاید؛ میانگین و صدک مکملاند و یکی همیشه جای دیگری را نمیگیرد.
مثال 10: آمادهسازی ایندکس و کاهش ورودی
فیلتر تاریخ قبل از محاسبه، داده نامرتبط را حذف و ایندکس پنجره را قابل استفادهتر میکند.
CREATE TABLE #Metric(ServiceId int,EventDate date,Value int);
INSERT #Metric VALUES(1,'2026-07-01',80),(1,'2026-07-02',100),(1,'2026-07-03',500),(2,'2026-07-01',50);
CREATE INDEX IX_Metric_Window ON #Metric(ServiceId,Value) INCLUDE(EventDate);
SELECT DISTINCT ServiceId,PERCENTILE_DISC(0.9) WITHIN GROUP(ORDER BY Value) OVER(PARTITION BY ServiceId) AS P90
FROM #Metric WHERE EventDate>='2026-07-01';
DROP TABLE #Metric;
| کنترل | مقدار |
|---|
| شاخص طرح اجرا | Sort، Memory Grant و Spill |
نکته کاربردی: فیلتر فقط وقتی مجاز است که دوره آماری موردنظر را دقیقاً نمایندگی کند؛ حذف داده برای سریعتر شدن نباید تعریف KPI را عوض کند.
سؤالات متداول
۱. تابع PERCENTILE_DISC دقیقاً چه مسئلهای را حل میکند؟
این تابع برای انتخاب مقدار واقعی موجود در مجموعه برای میانه، SLA و آستانههای قابل گزارش طراحی شده است. مزیت اصلی آن حفظ ردیفهای جزئی در کنار محاسبه تحلیلی است و برخلاف GROUP BY الزاماً تعداد ردیفها را کاهش نمیدهد.
۲. اجزای OVER در PERCENTILE_DISC چه نقشی دارند؟
PARTITION BY مرز گروه منطقی را تعیین میکند و ORDER BY توالی تحلیل را میسازد. در توابع حساس به Frame، عبارت ROWS نیز دامنه ردیفهای قابل مشاهده از هر ردیف را مشخص میکند.
۳. آیا استفاده از PERCENTILE_DISC هزینه توسعه گزارش را کم میکند؟
در بسیاری از گزارشها حذف Self Join، Cursor یا کد میانی باعث Query کوتاهتر و نگهداری سادهتر میشود. برای برآورد تجاری باید حجم داده، SLA، دفعات اجرا و هزینه ایندکس نیز اندازهگیری شود.
۴. چه زمانی بازطراحی Queryهای قدیمی با PERCENTILE_DISC ارزش اقتصادی دارد؟
اگر گزارش پرتکرار، زمانبر یا مستعد خطای محاسباتی باشد، بازطراحی میتواند زمان پشتیبانی و مصرف منابع را کم کند. یک ارزیابی یا مشاوره SQL Server با خط مبنای قبل و بعد، تصمیم سرمایهگذاری را مستند میکند.
۵. تفاوت PERCENTILE_DISC با گزینه نزدیک آن چیست؟
PERCENTILE_CONT ممکن است درونیابی کند؛ PERCENTILE_DISC نخستین مقدار با توزیع تجمعی کافی را برمیگزیند. انتخاب نهایی باید براساس تعریف دقیق خروجی، رفتار tie، NULL و مرز پنجره انجام شود.
۶. برای پیادهسازی حرفهای PERCENTILE_DISC در پروژه سازمانی چه خدمتی لازم است؟
ابتدا Query و Execution Plan واقعی بررسی، سپس ایندکس و آزمون صحت روی داده مرزی طراحی میشود. خدمات تحلیل، آموزش تیم یا بهینهسازی پروژه میتواند این مراحل را با معیار پذیرش روشن اجرا کند.
۷. رایجترین خطا در PERCENTILE_DISC چیست؟
در دادههای پلهای یا دارای تکرار زیاد، خروجی میتواند جهشی باشد و با میانگین یا میانه پیوسته تفاوت کند. علاوه بر آن، فیلتر کردن داده پیش از محاسبه میتواند جمعیت آماری یا همسایههای پنجره را ناخواسته تغییر دهد.
۸. چگونه Performance تابع PERCENTILE_DISC را بسنجیم؟
کاهش عرض ردیف، ایندکس همراستا و حذف داده نامرتبط پیش از Window Aggregate، هزینه را کنترل میکند. Actual Execution Plan، SET STATISTICS IO/TIME، Memory Grant، هشدار Spill و تعداد ردیف واقعی ابزارهای اصلی اندازهگیری هستند.
۹. بهترین روش نوشتن PERCENTILE_DISC چیست؟
ترتیب قطعی با tie-breaker یکتا، پارتیشن متناسب با منطق کسبوکار، تبدیل نوع صریح و آزمون NULL و مرزها را رعایت کنید. ابتدا صحت و سپس سرعت را بهینه سازید.
۱۰. PERCENTILE_DISC با کدام نسخههای SQL Server سازگار است؟
SQL Server 2012 و Compatibility Level 110 یا بالاتر. در Azure SQL نیز اصل قابلیت در دسترس است، اما Compatibility Level و اصلاحات تجمعی مرتبط با IGNORE NULLS یا Optimizer باید بررسی شود.