آموزش پیشرفته مرتب‌سازی داده‌ها در SQL Server با ORDER BY

تسلط بر مرتب‌سازی داده‌ها در SQL Server: تکنیک‌های پیشرفته ORDER BY برای هر پرس‌وجو

در مدیریت و تحلیل داده‌ها، مرتب‌سازی نتایج یک پرس‌وجو یکی از عملیات بنیادین است که با استفاده از عبارت `ORDER BY` در SQL Server انجام می‌شود. این عبارت امکان می‌دهد تا ردیف‌های بازگشتی را بر اساس یک یا چند ستون، به ترتیب صعودی (ASC) یا نزولی (DESC) منظم کنیم و به این ترتیب، خوانایی و کارایی گزارش‌گیری از داده‌ها را به شکل چشمگیری افزایش دهیم. در ادامه به بررسی کاربردهای پیشرفته `ORDER BY` می‌پردازیم که فراتر از مرتب‌سازی ساده است و برای سناریوهای پیچیده‌تر مفید خواهد بود.

یکی از چالش‌های رایج، نمایش تعداد مشخصی از ردیف‌ها به همراه ردیف‌هایی است که با آن‌ها “مساوی” (Ties) هستند. SQL Server توابع پنجره‌ای قدرتمندی مانند `ROW_NUMBER()`, `RANK()`, `DENSE_RANK()`, و `NTILE()` را ارائه می‌دهد که در ترکیب با `ORDER BY` می‌توانند این نیاز را برآورده سازند.

برای مثال، اگر بخواهیم ردیف‌ها را شماره‌گذاری کنیم یا بر اساس رتبه مرتب کنیم، از این توابع استفاده می‌شود:


ROW_NUMBER() OVER (ORDER BY Salary DESC) AS RowNum
RANK() OVER (ORDER BY Salary DESC) AS RankNum
DENSE_RANK() OVER (ORDER BY Salary DESC) AS DenseRankNum
NTILE(4) OVER (ORDER BY Salary DESC) AS NtileNum

* `ROW_NUMBER()` به هر ردیف، یک شماره منحصربه‌فرد بر اساس ترتیب مشخص‌شده می‌دهد.
* `RANK()` رتبه را به ردیف‌ها اختصاص می‌دهد و در صورت تساوی (Ties)، رتبه یکسان می‌دهد و رتبه بعدی را از دست می‌دهد (مثلاً 1, 1, 3).
* `DENSE_RANK()` نیز رتبه را بر اساس تساوی‌ها یکسان می‌دهد، اما هیچ رتبه‌ای را از دست نمی‌دهد (مثلاً 1, 1, 2).
* `NTILE(n)` ردیف‌ها را به `n` گروه مساوی تقسیم می‌کند و شماره گروه را برمی‌گرداند.

این توابع اغلب در یک Common Table Expression (CTE) یا ساب‌کوئری (Subquery) استفاده می‌شوند تا بتوان روی نتایج فیلترگذاری کرد.
به عنوان مثال برای انتخاب 5 ردیف برتر با استفاده از `ROW_NUMBER()`:


WITH RankedEmployees AS (
    SELECT
        EmployeeID,
        FirstName,
        LastName,
        Salary,
        ROW_NUMBER() OVER (ORDER BY Salary DESC) AS rn
    FROM
        HumanResources.Employee
)
SELECT
    EmployeeID,
    FirstName,
    LastName,
    Salary
FROM
    RankedEmployees
WHERE
    rn <= 5;

این پرس‌وجو 5 کارمند با بالاترین حقوق را بازمی‌گرداند.

یکی دیگر از کاربردهای پیشرفته `ORDER BY`، پیاده‌سازی پیمایش صفحه‌بندی (Paging) با استفاده از `OFFSET` و `FETCH` است که در SQL Server 2012 و نسخه‌های جدیدتر معرفی شد. این روش جایگزینی کارآمدتر برای روش‌های قدیمی‌تر `ROW_NUMBER()` است، به خصوص برای برنامه‌های وب که نیاز به بارگذاری داده‌ها به صورت صفحه به صفحه دارند.


SELECT
    EmployeeID,
    FirstName,
    LastName,
    JobTitle,
    HireDate
FROM
    HumanResources.Employee
ORDER BY
    HireDate DESC, EmployeeID ASC
OFFSET 10 ROWS
FETCH NEXT 5 ROWS ONLY;

این پرس‌وجو 5 ردیف را پس از پرش از 10 ردیف اول (یعنی ردیف‌های 11 تا 15) بر اساس تاریخ استخدام نزولی و سپس EmployeeID صعودی بازمی‌گرداند. این روش برای پیاده‌سازی قابلیت‌های صفحه‌بندی در وب‌سایت‌ها و اپلیکیشن‌ها بسیار مناسب است.

مرتب‌سازی شرطی با استفاده از عبارت `CASE` داخل `ORDER BY` یک ابزار قدرتمند است که به ما امکان می‌دهد ترتیب مرتب‌سازی را بر اساس مقادیر یک ستون یا هر شرط منطقی دیگری تغییر دهیم. این کار برای سناریوهایی که ترتیب خاصی بر اساس منطق تجاری مورد نیاز است، بسیار کارآمد است.


SELECT
    ProductLine,
    Name,
    ListPrice
FROM
    Production.Product
ORDER BY
    CASE ProductLine
        WHEN 'R' THEN 1  -- Road Bikes first
        WHEN 'M' THEN 2  -- Mountain Bikes second
        WHEN 'T' THEN 3  -- Touring Bikes third
        ELSE 4           -- Other products last
    END,
    ListPrice DESC;      -- Then sort by price descending within each group

در این مثال، محصولات ابتدا بر اساس خط تولید به ترتیب خاصی مرتب می‌شوند (R, M, T، سپس بقیه) و در هر گروه، بر اساس قیمت نزولی مرتب می‌شوند.

گاهی لازم است نتایج بر اساس یک ستون محاسباتی مرتب شوند. این ستون می‌تواند در عبارت `SELECT` تعریف شده باشد یا مستقیماً در `ORDER BY` مورد استفاده قرار گیرد.


SELECT
    FirstName,
    LastName,
    OrderQty,
    UnitPrice,
    OrderQty * UnitPrice AS TotalPrice
FROM
    Sales.SalesOrderDetail
ORDER BY
    TotalPrice DESC; -- Ordering by the calculated column alias

در این حالت، نتایج بر اساس `TotalPrice` که یک ستون محاسباتی است، به صورت نزولی مرتب می‌شوند. این کار باعث می‌شود بتوانیم ردیف‌ها را بر اساس معیارهای پیچیده‌تر که نیاز به محاسبه دارند، منظم کنیم.

SQL Server این امکان را می‌دهد که حتی بر اساس ستونی مرتب کنیم که در عبارت `SELECT` انتخاب نشده است، البته با محدودیت‌هایی که در مستندات مایکروسافت ذکر شده است. این قابلیت زمانی مفید است که بخواهیم ترتیب را بر اساس ستونی خاص تعیین کنیم اما نیازی به نمایش آن ستون در خروجی نداریم.


SELECT
    Name,
    ListPrice
FROM
    Production.Product
ORDER BY
    ModifiedDate DESC; -- Ordering by ModifiedDate, which is not in SELECT

این پرس‌وجو محصولات را بر اساس تاریخ آخرین تغییر (ModifiedDate) به صورت نزولی مرتب می‌کند، بدون اینکه آن ستون در نتایج نهایی نمایش داده شود.

همچنین می‌توانیم نتایج را بر اساس یک عبارت (Expression) مرتب کنیم. این عبارت می‌تواند شامل توابع رشته‌ای، عددی یا تاریخ باشد که نتایج را بر اساس یک محاسبه یا قسمتی از یک ستون مرتب می‌کند.


SELECT
    FirstName,
    LastName
FROM
    Person.Person
ORDER BY
    SUBSTRING(LastName, 1, 1) ASC; -- Ordering by the first letter of LastName

در این مثال، افراد بر اساس حرف اول نام خانوادگی خود به صورت صعودی مرتب می‌شوند.

در برخی موارد خاص، مانند انتخاب نمونه‌های تصادفی یا نمایش داده‌ها به ترتیبی نامنظم، می‌توان از تابع `RAND()` برای مرتب‌سازی تصادفی استفاده کرد. هرچند `RAND()` به تنهایی در `ORDER BY` ممکن است نتایج کاملاً تصادفی را تضمین نکند و برای نتایج واقعاً تصادفی، رویکردهای پیچیده‌تری با استفاده از `NEWID()` توصیه می‌شود.


SELECT TOP 10
    Name
FROM
    Production.Product
ORDER BY
    NEWID(); -- Ordering randomly using NEWID()

این پرس‌وجو 10 محصول تصادفی را بازمی‌گرداند. استفاده از `NEWID()` یک GUID منحصربه‌فرد برای هر ردیف تولید می‌کند که به صورت تصادفی مرتب می‌شوند و به این ترتیب، نتایج تصادفی‌تری نسبت به `RAND()` در `ORDER BY` ارائه می‌دهد. این تکنیک برای انتخاب نمونه‌های تصادفی از داده‌ها یا نمایش محتوای متنوع در هر بارگذاری صفحه، کاربرد فراوانی دارد.

به کارگیری این تکنیک‌های پیشرفته `ORDER BY` در SQL Server، به تحلیلگران داده و توسعه‌دهندگان کمک می‌کند تا پرس‌وجوهای پیچیده‌تر و کارآمدتری را برای مدیریت، نمایش و گزارش‌گیری از داده‌ها ایجاد کنند. درک این مفاهیم، کلید بهینه‌سازی عملکرد پایگاه داده و ارائه اطلاعات دقیق و سازمان‌یافته به کاربران نهایی است.

من علی دستجردی‌ام؛ عاشق کار با دیتا، از SQL Server تا بیگ‌دیتا و هوش مصنوعی. دغدغه‌ام کشف ارزش داده‌ها و به‌اشتراک‌گذاری تجربه‌هاست. ✦ رزومه من: alidastjerdi.com ✦

عضویت
منو باخبر کن!!!
guest
نام
ایمیل

0 دیدگاه
Inline Feedbacks
دیدن تمامی کامنتها

فوتر سایت

ورود به سایت

sqlyar

هنوز عضو نیستید؟

ورود به سایت

هنوز تبت نام نکردید ؟