مثالهای عملی مستقل و قابل اجرا
مثال 1: محاسبه میانه کل داده
صدک 0.5 با PERCENTILE_CONT میانه درونیابیشده را میسازد.
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 Median FROM D;
| تابع | میانه |
|---|
| PERCENTILE_CONT | 25.0 |
نکته کاربردی: DISTINCT فقط تکرار مقدار پنجرهای در خروجی نمایشی را حذف میکند؛ محاسبه روی همه ردیفها انجام شده است.
مثال 2: صدک نودم زمان پاسخ
در پایش SLA، صدک 0.9 تجربه کاربران کند را بهتر از میانگین نشان میدهد.
WITH R AS (SELECT Ms FROM (VALUES (80),(90),(100),(120),(500))V(Ms))
SELECT DISTINCT PERCENTILE_CONT(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_CONT(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_CONT(0.25) WITHIN GROUP(ORDER BY Value) OVER() AS P25,
PERCENTILE_CONT(0.50) WITHIN GROUP(ORDER BY Value) OVER() AS P50,
PERCENTILE_CONT(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_CONT(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_CONT(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_CONT(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_CONT(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_CONT(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_CONT دقیقاً چه مسئلهای را حل میکند؟
این تابع برای محاسبه میانه و صدکهای عددی با درونیابی میان مقادیر مجاور طراحی شده است. مزیت اصلی آن حفظ ردیفهای جزئی در کنار محاسبه تحلیلی است و برخلاف GROUP BY الزاماً تعداد ردیفها را کاهش نمیدهد.
۲. اجزای OVER در PERCENTILE_CONT چه نقشی دارند؟
PARTITION BY مرز گروه منطقی را تعیین میکند و ORDER BY توالی تحلیل را میسازد. در توابع حساس به Frame، عبارت ROWS نیز دامنه ردیفهای قابل مشاهده از هر ردیف را مشخص میکند.
۳. آیا استفاده از PERCENTILE_CONT هزینه توسعه گزارش را کم میکند؟
در بسیاری از گزارشها حذف Self Join، Cursor یا کد میانی باعث Query کوتاهتر و نگهداری سادهتر میشود. برای برآورد تجاری باید حجم داده، SLA، دفعات اجرا و هزینه ایندکس نیز اندازهگیری شود.
۴. چه زمانی بازطراحی Queryهای قدیمی با PERCENTILE_CONT ارزش اقتصادی دارد؟
اگر گزارش پرتکرار، زمانبر یا مستعد خطای محاسباتی باشد، بازطراحی میتواند زمان پشتیبانی و مصرف منابع را کم کند. یک ارزیابی یا مشاوره SQL Server با خط مبنای قبل و بعد، تصمیم سرمایهگذاری را مستند میکند.
۵. تفاوت PERCENTILE_CONT با گزینه نزدیک آن چیست؟
PERCENTILE_DISC یک مقدار موجود را انتخاب میکند؛ PERCENTILE_CONT بین دو مقدار نیز درونیابی میکند. انتخاب نهایی باید براساس تعریف دقیق خروجی، رفتار tie، NULL و مرز پنجره انجام شود.
۶. برای پیادهسازی حرفهای PERCENTILE_CONT در پروژه سازمانی چه خدمتی لازم است؟
ابتدا Query و Execution Plan واقعی بررسی، سپس ایندکس و آزمون صحت روی داده مرزی طراحی میشود. خدمات تحلیل، آموزش تیم یا بهینهسازی پروژه میتواند این مراحل را با معیار پذیرش روشن اجرا کند.
۷. رایجترین خطا در PERCENTILE_CONT چیست؟
عبارت صدک باید بین صفر و یک باشد و ORDER BY این تابع فقط یک عبارت عددی میپذیرد. علاوه بر آن، فیلتر کردن داده پیش از محاسبه میتواند جمعیت آماری یا همسایههای پنجره را ناخواسته تغییر دهد.
۸. چگونه Performance تابع PERCENTILE_CONT را بسنجیم؟
روی داده حجیم، پیشتجمیع معتبر، پارتیشنبندی محدود و کنترل Sort/Spill اثر زیادی بر زمان اجرا دارد. Actual Execution Plan، SET STATISTICS IO/TIME، Memory Grant، هشدار Spill و تعداد ردیف واقعی ابزارهای اصلی اندازهگیری هستند.
۹. بهترین روش نوشتن PERCENTILE_CONT چیست؟
ترتیب قطعی با tie-breaker یکتا، پارتیشن متناسب با منطق کسبوکار، تبدیل نوع صریح و آزمون NULL و مرزها را رعایت کنید. ابتدا صحت و سپس سرعت را بهینه سازید.
۱۰. PERCENTILE_CONT با کدام نسخههای SQL Server سازگار است؟
SQL Server 2012 و Compatibility Level 110 یا بالاتر. در Azure SQL نیز اصل قابلیت در دسترس است، اما Compatibility Level و اصلاحات تجمعی مرتبط با IGNORE NULLS یا Optimizer باید بررسی شود.