خانه/ مبانی SQL/ ORDER BY

ORDER BY: مرتب‌سازی نتیجه‌ی پرس‌وجو

مبتدی ۱۲ دقیقه مطالعه

تا اینجا هر پرس‌وجویی نوشتیم، نتیجه به هر ترتیبی که SQL Server داخلی پیدایش کرده برگشته — نه لزوماً بر اساس id یا هر ترتیب منطقی دیگری. ORDER BY این کنترل را به دست خودمان می‌دهد: می‌گوییم دقیقاً نتیجه به چه ترتیبی نمایش داده شود.

نکته‌ی مهم مفهومی: یک جدول در پایگاه‌داده‌ی رابطه‌ای، اصولاً یک «مجموعه» است، نه یک لیست مرتب. اگر ORDER BY ننویسی، SQL Server هیچ تعهدی به حفظ ترتیب خاصی (مثلاً ترتیب درج) نمی‌دهد — حتی اگر در عمل، در یک اجرای خاص، نتیجه اتفاقی مرتب به‌نظر برسد. تنها راه تضمینی برای ترتیب مشخص، همیشه نوشتن ORDER BY است.

ساختار پایه و جهت مرتب‌سازی

sql
SELECT full_name, grade
FROM students
ORDER BY grade ASC;   -- از کوچک به بزرگ (پیش‌فرض)

SELECT full_name, grade
FROM students
ORDER BY grade DESC;  -- از بزرگ به کوچک

اگر ASC یا DESC را ننویسی، پیش‌فرض همیشه ASC (صعودی) است.

مرتب‌سازی بر اساس چند ستون

می‌توان چند ستون را با هم مشخص کرد؛ ستون اول اولویت اصلی مرتب‌سازی است، و ستون‌های بعدی فقط برای شکستن تساوی (زمانی که چند ردیف در ستون اول مقدار یکسانی دارند) به‌کار می‌روند:

sql
SELECT full_name, city, grade
FROM students
ORDER BY city ASC, grade DESC;

یعنی: اول بر اساس شهر (الفبایی) مرتب کن؛ و در میان دانش‌آموزانی که شهرشان یکسان است، آن‌ها را بر اساس پایه از بزرگ به کوچک بچین. هر ستون در ORDER BY می‌تواند جهت مرتب‌سازی مستقل خودش را داشته باشد.

بیا این را روی داده‌ی واقعی امتحان کنیم:

امتحانش کن — مرتب‌سازی چندستونی

ORDER BY و نام مستعار: برخلاف WHERE، این‌جا مجاز است!

در درس WHERE دیدیم که (در SQL Server) نمی‌شود نام مستعار ساخته‌شده در SELECT را داخل WHERE همان پرس‌وجو استفاده کرد. اما در ORDER BY دقیقاً برعکس است — کاملاً مجاز و رایج است:

sql
SELECT full_name, grade + 1 AS NextYear
FROM students
ORDER BY NextYear DESC;

دلیلش دقیقاً همان «ترتیب پردازش منطقی» است که چند بار به آن اشاره کردیم: ORDER BY آخرین مرحله‌ای است که اجرا می‌شود — یعنی بعد از SELECT. تا آن لحظه، نام مستعار NextYear از قبل ساخته شده و کاملاً در دسترس ORDER BY است.

یادآوری ترتیب پردازش منطقی: FROMWHEREGROUP BYHAVINGSELECTORDER BY. همین ترتیب توضیح می‌دهد چرا WHERE به نام مستعار دسترسی ندارد ولی ORDER BY دارد.

بیا این را هم امتحان کنیم:

امتحانش کن — ORDER BY با نام مستعار

مرتب‌سازی بر اساس موقعیت ستون (روش قدیمی)

یک روش قدیمی‌تر این است که به‌جای نام ستون، شماره‌ی موقعیتش در لیست SELECT را بنویسی:

sql
SELECT full_name, city, grade
FROM students
ORDER BY 3 DESC;  -- یعنی همان grade، چون سومین ستون لیست است
توصیه: از این روش در کد واقعی پرهیز کن. اگر روزی ترتیب یا تعداد ستون‌های SELECT عوض شود، ORDER BY بدون این‌که خطایی بدهد، بی‌سروصدا ستون اشتباهی را مرتب می‌کند. نوشتن نام صریح ستون یا نام مستعار، همیشه امن‌تر است.

NULL کجای ترتیب مرتب‌سازی قرار می‌گیرد؟

در SQL Server، مقادیر NULL در مرتب‌سازی ASC همیشه اول لیست قرار می‌گیرند (چون NULL «کوچک‌ترین» مقدار ممکن در نظر گرفته می‌شود)، و در DESC برعکس، آخر لیست می‌آیند. نکته‌ی جالب این‌جاست که این رفتار بین پایگاه‌داده‌های مختلف یکسان نیست — مثلاً PostgreSQL به‌طور پیش‌فرض دقیقاً برعکس عمل می‌کند (NULL آخر لیست در ASC).

sql
SELECT full_name, grade
FROM students
ORDER BY grade ASC;

بیا این را روی همان جدولی که چند مقدار NULL داشت (از درس قبل) امتحان کنیم:

امتحانش کن — جای NULL در مرتب‌سازی
می‌بینی که هر دو ردیف با grade نامشخص، اول لیست قرار گرفتند — دقیقاً همان رفتار SQL Server. خوشبختانه SQLite (موتور همین Playground) هم در این مورد خاص، هم‌رفتار با SQL Server است.

مرتب‌سازی متن و نکته‌ی Collation

وقتی متن مرتب می‌شود، قوانین مرتب‌سازی از همان Collation پایگاه‌داده پیروی می‌کند که در درس پایگاه‌های داده به آن اشاره کردیم — یعنی این‌که آیا حروف بزرگ و کوچک یکسان در نظر گرفته می‌شوند، و ترتیب الفبایی طبق کدام زبان تعیین می‌شود. برای متن فارسی، کولیشن مناسب مثل Persian_100_CI_AS باعث می‌شود ترتیب حروف الفبای فارسی، مطابق انتظار واقعی‌مان باشد.

یک قانون نحوی مهم: ORDER BY همیشه آخر است

از نظر نوشتاری هم، ORDER BY باید همیشه آخرین بخش پرس‌وجو باشد — بعد از WHERE، و در فصل‌های بعد بعد از GROUP BY و HAVING هم:

sql
SELECT full_name, city, grade
FROM students
WHERE grade IS NOT NULL
ORDER BY grade DESC;
نکته‌ی کارایی: مرتب‌سازی روی جدول‌های خیلی بزرگ می‌تواند پرهزینه باشد، چون SQL Server باید همه‌ی ردیف‌های واجدشرایط را قبل از نمایش، کامل مرتب کند. یک ایندکس مناسب روی ستون مرتب‌سازی می‌تواند این هزینه را به‌شدت کاهش دهد — موضوعی که در فصل ۱۰ کامل بررسی می‌کنیم.

جمع‌بندی این درس

  • بدون ORDER BY، هیچ ترتیب تضمین‌شده‌ای برای نتیجه‌ی پرس‌وجو وجود ندارد.
  • ASC (پیش‌فرض) صعودی است، DESC نزولی.
  • چند ستون در ORDER BY یعنی ستون‌های بعدی، تساوی ستون‌های قبلی را می‌شکنند.
  • بر خلاف WHERE، در ORDER BY استفاده از نام مستعار SELECT کاملاً مجاز است — چون منطقاً آخرین مرحله‌ی پردازش است.
  • مرتب‌سازی بر اساس شماره‌ی موقعیت ستون، فقط برای کد واقعی توصیه نمی‌شود.
  • در SQL Server (و SQLite)، مقادیر NULL در ASC اول لیست می‌آیند.

در درس بعدی سراغ TOP می‌رویم: یاد می‌گیریم چطور فقط چند ردیف اول نتیجه را نگه داریم — مثلاً «۵ دانش‌آموز برتر».