پرش به محتوا

Select (SQL)

از ویکی‌پدیا، دانشنامهٔ آزاد
نسخهٔ قابل چاپ دیگر پشتیبانی نمی‌شود و ممکن است در زمان رندر کردن با خطا مواجه شوید. لطفاً بوکمارک‌های مرورگر خود را به‌روزرسانی کنید و در عوض از عمبکرد چاپ پیش‌فرض مرورگر خود استفاده کنید.

دستور SQL SELECT مجموعه‌ای از سطرها را که از یک یا چند جدول استخراج می‌شوند، به عنوان نتیجه بازمیگرداند. [۱] [۲]

یک دستور SELECT برای بازیابی صفر یا چند ردیف از یک یا چند جدول پایگاه داده یا نمای پایگاه داده استفاده می‌شود. در اکثر برنامه ها، SELECT رایج ترین فرمان زبان دستکاری داده ها (DML) است. از آنجا که SQL یک زبان برنامه نویسی اعلانی است، دستورات SELECT تنها مجموعه نتایج مورد نظر را مشخص می کنند، اما نحوه محاسبه آن را تعیین نمی نمایند. پایگاه داده این پرس‌وجو را به یک " طرح پرس‌وجو " تبدیل می‌کند که ممکن است در اجراهای مختلف، نسخه‌های متفاوت پایگاه داده یا نرم‌افزار پایگاه داده تفاوت داشته باشد. این قابلیت تحت عنوان " بهینه ساز پرس‌وجو " نام دارد و هدف آن یافتن بهینه‌ترین طرح اجرایی ممکن برای اجرای پرس‌وجو، در چارچوب محدودیت های موجود است.

دستور SELECT دارای بندهای اختیاری زیادی است:

  • لیست SELECT لیستی از ستون ها یا عبارات SQL است که باید توسط پرس و جو برگردانده شوند. این تقریباً عملیات طرح ریزی جبر رابطه ای است.
  • AS به صورت اختیاری یک نام مستعار برای هر ستون یا عبارت در لیست SELECT ارائه می دهد. این عملیات تغییر نام جبر رابطه ای است.
  • FROM مشخص می کند که داده ها از کدام جدول دریافت شود.
  • WHERE مشخص می کند که کدام ردیف ها باید بازیابی شوند. این تقریباً عملیات انتخاب جبر رابطه ای است.
  • GROUP BY ردیف‌هایی را گروه‌بندی می‌کند که یک ویژگی را به اشتراک می‌گذارند تا بتوان یک تابع تجمیع را برای هر گروه اعمال کرد.
  • HAVING از بین گروه های تعریف شده توسط بند GROUP BY انتخاب می کند.
  • ORDER BY نحوه ترتیب ردیف های برگشتی را مشخص می کند.
  • کلیدواژه DISTINCT داده‌های تکراری را حذف می‌کند.

نمای کلی

دستور SELECT رایج ترین عملیات در SQL محسوب می‌شود که «پرس‌وجو» نامیده می شود. این دستور داده‌ها را از یک یا چند جدول یا عبارت بازیابی می‌کند. اجرای یک دستور SELECT استاندارد، معمولاً تأثیری ماندگار بر پایگاه‌داده نمی‌گذارد؛ با این حال، برخی پیاده‌سازی های غیر استاندارد مانند SELECT INTO ممکن است تغییرات دائمی ایجاد کنند.

پرس‌وجو‌ها به کاربر اجازه می‌دهند تا داده‌های مورد نظر خود را توصیف کند، در حالی که سیستم مدیریت پایگاه داده (DBMS) وظیفه برنامه‌ریزی ، بهینه‌سازی و اجرای عملیات فیزیکی لازم برای تولید نتیجه را بر عهده دارد.

هر پرس‌وجو شامل فهرستی از ستون‌هاست که باید در نتیجه نهایی نمایش داده شوند، که معمولاً بلافاصله پس از کلیدواژه SELECT قرار می گیرد. برای نمایش همه ستون های جدول، میتوان از علامت ستاره (" * ") استفاده کرد. SELECT پیچیده ترین دستور در SQL به شمار می‌رود و می‌تواند شامل کلیدواژه‌ها و بند‌های اختیاری گوناگونی باشد از جمله [۱][۲]ORDER BY, HAVING, GROUP BY, FROM, WHERE.


مثال زیر از یک پرس‌وجوی SELECT را نشان می‌دهد که فهرستی از کتاب‌های گران‌قیمت را برمی‌گرداند. این پرس‌وجو تمامی ردیف‌های جدول Book را بازیابی می‌کند که مقدار ستون price آن‌ها حاوی مقداری بزرگتر از 100.00 باشد. نتایج بر اساس title به صورت صعودی مرتب می‌شوند. علامت ستاره (*) در فهرست انتخاب نشان می‌دهد که تمام ستون‌های جدول Book باید در مجموعه نتایج گنجانده شوند.

SELECT *
 FROM  Book
 WHERE price > 100.00
 ORDER BY title;
SELECT *
    FROM Book
    WHERE price > 100.100
    ORDER BY title;

مثال زیر یک پرس‌وجو با چند جدول، گروه‌بندی و تجمیع را نشان می‌دهد؛ به این صورت که فهرستی از کتاب‌ها و تعداد نویسندگان مرتبط با هر کتاب را بازمی‌گرداند.

    SELECT Book.title AS Title,
           count(*) AS Authors
     FROM  Book
     JOIN  Book_author
       ON  Book.isbn = Book_author.isbn
 GROUP BY Book.title;
  1. Microsoft (23 May 2023). "Transact-SQL Syntax Conventions".
  2. MySQL. "SQL SELECT Syntax".

خروجی مثال ممکن است شبیه به زیر باشد:

عنوان                                نویسندگان
---------------------- -------
مثال‌ها و راهنمای اس‌کیو‌ال       4    
لذت اس‌کیو‌ال                          1
مقدمه‌ای بر اس‌کیو‌ال                2  
مشکلات اس‌کیوال                    1 

با فرض اینکه ستون isbn تنها نام مشترک بین دو جدول است و ستون title فقط در جدول Book وجود دارد، می‌توان پرس‌وجوی بالا را به شکل زیر بازنویسی کرد:

SELECT title,
       count(*) AS Authors
 FROM  Book
 NATURAL JOIN Book_author
 GROUP BY title;

با این حال، بسیاری از ارائه‌دهندگان پایگاه داده یا از این روش پشتیبانی نمی‌کنند، یا برای عملکرد صحیح NATURAL JOIN نیاز به رعایت نام‌گذاری خاصی برای ستون‌ها دارند.

SQL شامل عملگرها و توابعی برای انجام محاسبات بر روی داده‌های ذخیره‌شده است. این زبان امکان استفاده از عبارت‌ها را در فهرست SELECT فراهم می‌کند تا داده‌ها به‌صورت محاسبه‌شده نمایش یابند؛ مانند مثال زیر که فهرستی از کتاب‌های با قیمت بیش از ۱۰۰٫۰۰ را به همراه ستونی اضافی به نام sales_tax بازمی‌گرداند. مقدار این ستون بر اساس ۶٪ از قیمت هر کتاب محاسبه شده است.

SELECT isbn,
       title,
       price,
       price * 0.06 AS sales_tax
 FROM  Book
 WHERE price > 100.00
 ORDER BY title;

زیرپرس‌وجوها

پرس‌وجوها می‌توانند تو در تو نوشته شوند، به‌طوری که نتایج یک پرس‌وجو در پرس‌وجوی دیگر از طریق یک عملگر رابطه‌ای یا تابع تجمیعی مورد استفاده قرار گیرد. به چنین پرس‌وجوهایی «زیرپرس‌وجو» (Subquery) نیز گفته می‌شود. اگرچه در بسیاری از موارد استفاده از اتصال‌ها (Join) و سایر عملیات جدول از نظر محاسباتی عملکرد بهتری (سریع‌تر) دارند، اما زیرپرس‌وجوها ساختار سلسله‌مراتبی در اجرا ایجاد می‌کنند که در برخی موقعیت‌ها مفید یا ضروری است. در مثال زیر، تابع تجمیعی AVG نتیجه یک زیرپرس‌وجو را به‌عنوان ورودی دریافت می‌کند:

SELECT isbn,
       title,
       price
 FROM  Book
 WHERE price < (SELECT AVG(price) FROM Book)
 ORDER BY title;

زیرپرس‌وجو می‌تواند از مقادیر موجود در پرس‌وجوی بیرونی استفاده کند که در این صورت به آن «زیرپرس‌وجوی هم‌بسته» گفته می‌شود.

از سال ۱۹۹۹، استاندارد SQL استفاده از بندهای WITH را مجاز می‌داند، یعنی زیرپرس‌وجوهای نامگذاری‌شده که اغلب عبارات جدولی رایج نامیده می‌شوند (که پس از پیاده‌سازی IBM DB2 نسخه ۲ نامگذاری و طراحی شده‌اند؛ اوراکل این زیرپرس‌وجوها را فاکتورگیری می‌نامد). CTEها همچنین می‌توانند با ارجاع به خودشان باشند؛ مکانیسم حاصل، پیمایش درخت یا گراف (هنگامی که به صورت رابطه نمایش داده می‌شوند) و به طور کلی‌تر محاسبات امکان‌پذیر می‌سازد.

از سال ۱۹۹۹، استاندارد SQL اجازه استفاده از بند WITH را می‌دهد؛ این بند شامل زیرپرس‌وجوهای نام‌گذاری‌شده‌ای است که معمولاً «عبارات جدول مشترک» (Common Table Expressions یا CTE) نامیده می‌شوند. این مفهوم بر اساس پیاده‌سازی نسخه ۲ پایگاه داده IBM DB2 طراحی شده است؛ در پایگاه داده Oracle به آن subquery factoring گفته می‌شود. CTEها می‌توانند به‌صورت بازگشتی نیز تعریف شوند، یعنی به خودشان ارجاع دهند. این قابلیت امکان پیمایش ساختارهای درختی یا گرافی (در صورتی که به‌صورت رابطه‌ای نمایش داده شوند) و به‌طور کلی انجام محاسبات نقطه ثابت را فراهم می‌کند.

جدول مشتق شده

جدول مشتق‌شده زیرپرس‌وجویی است که در بند FROM قرار می‌گیرد. در اصل، جدول مشتق‌شده یک زیرپرس‌وجو است که می‌توان از آن انتخاب انجام داد یا آن را به جدول‌های دیگر متصل کرد. این قابلیت به کاربر اجازه می‌دهد تا به زیرپرس‌وجو همانند یک جدول ارجاع دهد. جدول مشتق‌شده همچنین با عناوینی مانند «نمای درون‌خطی» یا «انتخاب در فهرست FROM» نیز شناخته می‌شود.

در مثال زیر، دستور SQL شامل یک اتصال بین جدول اولیه‌ی Books و جدول مشتق‌شده‌ای به نام "Sales" است. این جدول مشتق‌شده اطلاعات مربوط به فروش کتاب‌ها را با استفاده از ستون ISBN به جدول Books متصل می‌کند. در نتیجه، جدول مشتق‌شده مجموعه نتایج را با ستون‌های اضافی مانند تعداد نسخه‌های فروخته‌شده و نام شرکتی که کتاب‌ها را فروخته است، تکمیل می‌کند.

SELECT b.isbn, b.title, b.price, sales.items_sold, sales.company_nm
FROM Book b
  JOIN (SELECT SUM(Items_Sold) Items_Sold, Company_Nm, ISBN
        FROM Book_Sales
        GROUP BY Company_Nm, ISBN) sales
  ON sales.isbn = b.isbn
Select * 
from {table} 
order by {unique_key}

مثال‌ها

جدول "T" پرس‌وجو نتیجه
C1 C2
1 a
2 b
SELECT * FROM T;
C1 C2
1 a
2 b
C1 C2
1 a
2 b
SELECT C1 FROM T;
C1
1
2
C1 C2
1 a
2 b
SELECT * FROM T WHERE C1 = 1;
C1 C2
1 a
C1 C2
1 a
2 b
SELECT * FROM T ORDER BY C1 DESC;
C1 C2
2 b
1 a
وجود ندارد SELECT 1+1, 3*2;
`1+1` `3*2`
2 6

با فرض وجود جدولی به نام T، اجرای پرس‌وجوی SELECT * FROM T باعث می‌شود تمام عناصر مربوط به تمام ردیف‌های جدول نمایش داده شوند.

با استفاده از همان جدول، اجرای پرس‌وجوی SELECT C1 FROM T موجب می‌شود که عناصر ستون C1 از تمامی ردیف‌های جدول نمایش داده شوند. این عمل مشابه «پروژکشن» در جبر رابطه‌ای است، با این تفاوت که در حالت کلی، ممکن است نتایج شامل ردیف‌های تکراری باشند. در برخی اصطلاحات پایگاه داده، به این نوع پرس‌وجو «پارتیشن‌بندی عمودی» نیز گفته می‌شود، چرا که خروجی پرس‌وجو را به نمایش فیلدها یا ستون‌های مشخص محدود می‌کند..

با استفاده از همان جدول، اجرای پرس‌وجوی SELECT * FROM T WHERE C1 = 1 باعث می‌شود تمام عناصر مربوط به ردیف‌هایی که مقدار ستون C1 آن‌ها برابر با '1' است نمایش داده شوند. در جبر رابطه‌ای، این عملیات به عنوان «انتخاب» شناخته می‌شود، زیرا شرطی از طریق بند WHERE اعمال شده است. این نوع فیلتر کردن ردیف‌ها در برخی مفاهیم پایگاه داده «پارتیشن‌بندی افقی» نامیده می‌شود، چرا که خروجی پرس‌وجو را بر اساس شرایط مشخص به مجموعه‌ای محدود از ردیف‌ها محدود می‌سازد.

در صورت استفاده از بیش از یک جدول، مجموعه نتایج شامل تمام ترکیب‌های ممکن از ردیف‌های جدول‌ها خواهد بود. برای مثال، اگر دو جدول T1 و T2 داشته باشیم، اجرای پرس‌وجوی SELECT * FROM T1, T2 موجب می‌شود هر ردیف از T1 با هر ردیف از T2 ترکیب شود. به‌عنوان نمونه، اگر T1 شامل ۳ ردیف و T2 شامل ۵ ردیف باشد، نتیجه نهایی شامل ۱۵ ردیف خواهد بود.

اگرچه این قابلیت در استاندارد SQL تعریف نشده است، اما اکثر سامانه‌های مدیریت پایگاه داده (DBMS) اجازه می‌دهند که از دستور SELECT بدون ارجاع به جدول خاصی استفاده شود؛ به‌طوری که گویی یک جدول فرضی با تنها یک ردیف وجود دارد. این ویژگی عمدتاً برای انجام محاسباتی به‌کار می‌رود که نیاز به جدول واقعی ندارند.

بند SELECT فهرستی از ویژگی‌ها (ستون‌ها) را با نام مشخص می‌کند، یا از نویسه‌ی عام (*) برای اشاره به «تمام ویژگی‌ها» استفاده می‌نماید.

محدود کردن ردیف‌های نتایج

اغلب مناسب است که حداکثر تعداد ردیف‌های بازگردانده‌شده در یک پرس‌وجو مشخص شود. این کار می‌تواند برای اهداف آزمایشی یا برای جلوگیری از مصرف بیش از حد منابع در مواقعی که پرس‌وجو داده‌هایی بیش از حد انتظار تولید می‌کند، مورد استفاده قرار گیرد. روش انجام این کار معمولاً در میان ارائه‌دهندگان مختلف پایگاه داده متفاوت است.

در ISO SQL:2003 ، مجموعه نتایج ممکن است با استفاده از موارد زیر محدود شوند:

ISO SQL:2008 بند FETCH FIRST را معرفی کرد.

بر اساس مستندات نسخه ۹ PostgreSQL، یک تابع پنجره‌ای در SQL «محاسبه‌ای را روی مجموعه‌ای از ردیف‌های جدول که به‌نوعی با ردیف جاری مرتبط هستند انجام می‌دهد»، و عملکردی مشابه توابع تجمیعی دارد. نام این توابع از توابع پنجره‌ای در پردازش سیگنال الهام گرفته شده است. فراخوانی یک تابع پنجره‌ای همواره شامل بند OVER می‌باشد.

تابع پنجره ()ROW_NUMBER

ROW_NUMBER() OVER می‌تواند برای یک جدول ساده با تعداد ردیف‌های برگردانده شده استفاده شود، مثلاً برای برگرداندن حداکثر ده ردیف:

SELECT * FROM
( SELECT
    ROW_NUMBER() OVER (ORDER BY sort_key ASC) AS row_number,
    columns
  FROM tablename
) AS foo
WHERE row_number <= 10


تابع ROW_NUMBER می‌تواند غیرقطعی باشد؛ به این معنا که اگر مقدار sort_key یکتا نباشد، ممکن است در هر بار اجرای پرس‌وجو، شماره ردیف‌های متفاوتی به ردیف‌هایی که مقدار sort_key یکسان دارند اختصاص داده شود. در صورتی که sort_key یکتا باشد، هر ردیف همواره یک شماره ردیف یکتا دریافت خواهد کرد.

تابع پنجره‌ای RANK()

تابع پنجره‌ای RANK() OVER مانند ROW_NUMBER عمل می‌کند، اما در صورت وجود شرایط مساوی، ممکن است تعداد ردیف‌های بیشتر یا کمتری از n را برگرداند، مثلاً برای بازگرداندن 10 نفر جوان‌تر:

SELECT * FROM (
  SELECT
    RANK() OVER (ORDER BY age ASC) AS ranking,
    person_id,
    person_name,
    age
  FROM person
) AS foo
WHERE ranking <= 10
Select * 
from {table} 
order by {unique_key}

کد بالا ممکن است بیش از ده ردیف بازگرداند؛ برای مثال، اگر دو نفر هم‌سن باشند، ممکن است یازده ردیف در نتیجه بازگردانده شود.

بند FETCH FIRST

از آنجا که محدودیت‌های نتایج ISO SQL:2008 را می‌توان مانند مثال زیر با استفاده از عبارت FETCH FIRST مشخص کرد.

SELECT * FROM T 
FETCH FIRST 10 ROWS ONLY

این بند در حال حاضر توسط CA DATACOM/DB نسخه ۱۱، IBM DB2، SAP SQL Anywhere، PostgreSQL، EffiProz، H2، HSQLDB نسخه ۲.۰، Oracle 12c و Mimer SQL پشتیبانی می‌شود. مایکروسافت SQL Server 2008 و بالاتر از FETCH FIRST پشتیبانی می‌کند ، اما بخشی از بند ORDER BY محسوب می‌شود. بندهای ORDER BY ، OFFSET و FETCH FIRST همگی برای این کاربرد ضروری هستند.

SELECT * FROM T 
ORDER BY acolumn DESC OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY
Select * 
from {table} 
order by {unique_key}

نگارش غیر استاندارد

برخی از سامانه‌های مدیریت پایگاه داده (DBMS) نگارش‌های غیراستانداردی را به‌جای نگارش استاندارد SQL یا علاوه بر آن ارائه می‌دهند. در ادامه، گونه‌های مختلف یک پرس‌وجوی ساده با محدودیت تعداد نتایج برای سامانه‌های مختلف فهرست شده‌اند:

SET ROWCOUNT 10
SELECT * FROM T
MS SQL Server (این روش همچنین در نسخه Microsoft SQL Server 6.5 نیز عمل می‌کند، در حالی که عبارت SELECT TOP 10 * FROM T در آن نسخه قابل استفاده نیست)
SELECT * FROM T 
LIMIT 10 OFFSET 20
Netezza، MySQL، MariaDB (از نسخه ۱۰٫۶ به بعد از نگارش استاندارد نیز پشتیبانی می‌کند)، SAP SQL Anywhere، PostgreSQL (از نسخه ۸٫۴ به بعد از نگارش استاندارد نیز پشتیبانی می‌کند)، SQLite، HSQLDB، H2، Vertica، Polyhedra، Couchbase Server، Snowflake Computing، و OpenLink Virtuoso
SELECT * from T 
WHERE ROWNUM <= 10
Oracle
SELECT FIRST 10 * from T Ingres
SELECT FIRST 10 * FROM T order by a Informix
SELECT SKIP 20 FIRST 10 * FROM T order by c, d Informix (شماره‌گذاری ردیف‌ها پس از ارزیابی بند ORDER BY فیلتر می‌شود. بند SKIP در نسخه‌ی v10.00.xC4 و با یک بسته‌ی اصلاحی معرفی شد)
SELECT TOP 10 * FROM T MS SQL Server, SAP ASE, MS Access, SAP IQ, Teradata
SELECT * FROM T 
SAMPLE 10
Teradata
SELECT TOP 20, 10 * FROM T OpenLink Virtuoso (۲۰ ردیف را رد کرده و ۱۰ ردیف بعدی را بازمی‌گرداند)
SELECT TOP 10 START AT 20 * FROM T SAP SQL Anywhere (از نسخه ۹٫۰٫۱ به بعد از نگارش استاندارد نیز پشتیبانی می‌کند)
SELECT FIRST 10 SKIP 20 * FROM T Firebird
SELECT * FROM T
ROWS 20 TO 30
Firebird (از ورژن ۲.۱)
SELECT * FROM T
WHERE ID_T > 10 FETCH FIRST 10 ROWS ONLY
IBM Db2
SELECT * FROM T
WHERE ID_T > 20 FETCH FIRST 10 ROWS ONLY
IBM Db2 (ردیف‌های جدید پس از مقایسه با ستون کلید جدول T فیلتر می‌شوند)


صفحه بندی ردیف ها

صفحه‌بندی ردیف‌ها رویکردی است که برای محدود کردن و نمایش تنها بخشی از کل داده‌های یک پرس‌وجو در پایگاه داده استفاده می‌شود. به‌جای نمایش صدها یا هزاران ردیف به‌صورت هم‌زمان، تنها یک صفحه (مجموعه‌ای محدود از ردیف‌ها، برای مثال فقط ۱۰ ردیف) از سرور درخواست می‌شود و کاربر با درخواست صفحه بعدی، و سپس صفحه بعد از آن، به مرور داده‌ها می‌پردازد. این روش به‌ویژه در سامانه‌های وب بسیار مفید است، جایی که اتصال اختصاصی بین کاربر و سرور وجود ندارد، بنابراین کاربر مجبور نیست منتظر بماند تا تمام ردیف‌های سرور بارگذاری و نمایش داده شوند.

رویکرد صفحه‌بندی داده‌ها

  • {rows} = تعداد سطرها در یک صفحه
  • {page_number} = شماره صفحه فعلی
  • {begin_base_0} = شماره ردیف - ۱ که صفحه از آن شروع می‌شود = (page_number-1) * ردیف‌ها

ساده‌ترین روش (اما بسیار ناکارآمد)

  1. انتخاب تمام سطرها از پایگاه داده
  2. همه ردیف‌ها را می‌خواند اما فقط زمانی نمایش می‌دهد که شماره ردیف ردیف‌های خوانده شده بین {begin_base_0 + 1} و {begin_base_0 + rows} باشد.
    Select * 
    from {table} 
    order by {unique_key}
    
sum(population) OVER( PARTITION BY city )

روش ساده دیگر (کمی کارآمدتر از خواندن همه ردیف‌ها)

  1. تمام ردیف‌ها را از ابتدای جدول تا آخرین ردیف برای نمایش انتخاب می‌کند ( {begin_base_0 + rows} )
  2. سطرهای {begin_base_0 + rows} را بخوانید، اما فقط زمانی که شماره سطر سطرهای خوانده شده بزرگتر از {begin_base_0} باشد، آن را برای نمایش ارسال کنید.
SQL گویش
select *
from {table}
order by {unique_key}
FETCH FIRST {begin_base_0 + rows} ROWS ONLY
SQL ANSI 2008

PostgreSQL SQL Server 2012 Derby Oracle 12c DB2 12 Mimer SQL

Select *
from {table}
order by {unique_key}
LIMIT {begin_base_0 + rows}
MySQL

SQLite

Select TOP {begin_base_0 + rows} * 
from {table} 
order by {unique_key}
SQL Server 2005
Select *
from {table}
order by {unique_key}
ROWS LIMIT {begin_base_0 + rows}
Sybase, ASE 16 SP2
SET ROWCOUNT {begin_base_0 + rows}
Select * 
from {table} 
order by {unique_key}
SET ROWCOUNT 0
Sybase, SQL Server 2000
Select *
    FROM (
        SELECT * 
        FROM {table} 
        ORDER BY {unique_key}
    ) a 
where rownum <= {begin_base_0 + rows}
Oracle 11


روش با موقعیت یابی

  1. فقط {rows} ردیف‌هایی را که از ردیف بعدی برای نمایش شروع می‌شوند، انتخاب کنید ( {begin_base_0 + 1} )
  2. خواندن و ارسال برای نمایش تمام ردیف‌های خوانده شده از پایگاه داده
SQL گویش
Select *
from {table}
order by {unique_key}
OFFSET {begin_base_0} ROWS
FETCH NEXT {rows} ROWS ONLY
SQL ANSI 2008

PostgreSQL SQL Server 2012 Derby Oracle 12c DB2 12 Mimer SQL

Select *
from {table}
order by {unique_key}
LIMIT {rows} OFFSET {begin_base_0}
MySQL

MariaDB PostgreSQL SQLite

Select * 
from {table} 
order by {unique_key}
LIMIT {begin_base_0}, {rows}
MySQL

MariaDB SQLite

Select *
from {table}
order by {unique_key}
ROWS LIMIT {rows} OFFSET {begin_base_0}
Sybase, ASE 16 SP2
Select TOP {begin_base_0 + rows}
       *,  _offset=identity(10) 
into #temp
from {table}
ORDER BY {unique_key} 
select * from #temp where _offset > {begin_base_0}
DROP TABLE #temp
Sybase 12.5.3:
SET ROWCOUNT {begin_base_0 + rows}
select *,  _offset=identity(10) 
into #temp
from {table}
ORDER BY {unique_key} 
select * from #temp where _offset > {begin_base_0}
DROP TABLE #temp
SET ROWCOUNT 0
Sybase 12.5.2:
select TOP {rows} * 
from (
      select *, ROW_NUMBER() over (order by {unique_key}) as _offset
      from {table}
) xx 
where _offset > {begin_base_0}
SQL Server 2005
SET ROWCOUNT {begin_base_0 + rows}
select *,  _offset=identity(int,1,1) 
into #temp
from {table}
ORDER BY {unique-key}
select * from #temp where _offset > {begin_base_0}
DROP TABLE #temp
SET ROWCOUNT 0
SQL Server 2000
SELECT * FROM (
    SELECT rownum-1 as _offset, a.* 
    FROM(
        SELECT * 
        FROM {table} 
        ORDER BY {unique_key}
    ) a 
    WHERE rownum <= {begin_base_0 + cant_regs}
)
WHERE _offset >= {begin_base_0}
Oracle 11

روش با فیلتر (پیچیده‌تر است اما برای مجموعه داده‌های بسیار بزرگ ضروری است)

  1. فقط ردیف‌های {rows} را با فیلتر انتخاب کنید:
    1. صفحه اول: فقط سطرهای اول {rows} را انتخاب کنید، بسته به نوع پایگاه داده
    2. صفحه بعد: فقط اولین {rows} سطرها را انتخاب کنید، بسته به نوع پایگاه داده، که در آن {unique_key} بزرگتر از {last_val} (مقدار {unique_key} آخرین سطر در صفحه فعلی) باشد.
    3. صفحه قبل: داده‌ها را به ترتیب معکوس مرتب کنید، فقط اولین {rows} ردیف‌ها را انتخاب کنید، که در آن {unique_key} کمتر از {first_val} (مقدار {unique_key} ردیف اول در صفحه فعلی) باشد، و نتیجه را به ترتیب صحیح مرتب کنید.
  2. خواندن و ارسال برای نمایش تمام ردیف‌های خوانده شده از پایگاه داده
صفحه‌‌ی اول صفحه‌ی بعدی صفحه‌ی قبلی
select *
from {table} 
order by {unique_key}
FETCH FIRST {rows} ROWS ONLY
select * 
from {table} 
where {unique_key} > {last_val}
order by {unique_key}
FETCH FIRST {rows} ROWS ONLY
select * 
 from (
   select * 
   from {table} 
   where {unique_key} < {first_val}
   order by {unique_key} DESC
   FETCH FIRST {rows} ROWS ONLY
 ) a
 order by {unique_key}
select *
from {table}
order by {unique_key}
LIMIT {rows}
select * 
from {table} 
where {unique_key} > {last_val}
order by {unique_key}
LIMIT {rows}
select * 
 from (
   select * 
   from {table} 
   where {unique_key} < {first_val}
   order by {unique_key} DESC
   LIMIT {rows}
 ) a
 order by {unique_key}
select TOP {rows} * 
from {table} 
order by {unique_key}
select TOP {rows} * 
from {table} 
where {unique_key} > {last_val}
order by {unique_key}
select * 
 from (
   select TOP {rows} * 
   from {table} 
   where {unique_key} < {first_val}
   order by {unique_key} DESC
 ) a
 order by {unique_key}
SET ROWCOUNT {rows}
select *
from {table} 
order by {unique_key}
SET ROWCOUNT 0
SET ROWCOUNT {rows}
select *
from {table} 
where {unique_key} > {last_val}
order by {unique_key}
SET ROWCOUNT 0
SET ROWCOUNT {rows}
 select *
 from (
   select * 
   from {table} 
   where {unique_key} < {first_val}
   order by {unique_key} DESC
 ) a
 order by {unique_key}
 SET ROWCOUNT 0
select *
from (
    select * 
    from {table} 
    order by {unique_key}
  ) a 
where rownum <= {rows}
select *
from (
  select * 
  from {table} 
  where {unique_key} > {last_val}
  order by {unique_key}
) a 
where rownum <= {rows}
select * 
 from (
   select *
   from (
     select * 
     from {table} 
     where {unique_key} < {first_val}
     order by {unique_key} DESC
   ) a1
   where rownum <= {rows}
 ) a2
 order by {unique_key}

پرس و جوی سلسله مراتبی

برخی پایگاه‌های داده نگارش‌های ویژه‌ای برای داده‌های سلسله‌مراتبی ارائه می‌دهند.

تابع پنجره‌ای در استاندارد SQL:2003، یک تابع تجمیعی است که بر روی یک پارتیشن از مجموعه نتایج اعمال می‌شود.

برای مثال،

Select * 
from {table} 
order by {unique_key}



مجموع جمعیت تمام ردیف‌هایی را محاسبه می‌کند که مقدار ستون city آن‌ها با ردیف جاری یکسان است.

پارتیشن‌ها با استفاده از بند OVER مشخص می‌شوند که تابع تجمیعی را تغییر می‌دهد. نگارش (Syntax):


بند OVER می‌تواند مجموعه نتایج را بخش‌بندی و مرتب‌سازی کند. مرتب‌سازی برای توابع وابسته به ترتیب مانند ROW_NUMBER مورد استفاده قرار می‌گیرد.

ارزیابی پرس و جو ANSI

پردازش یک دستور SELECT بر اساس استاندارد ANSI SQL به‌صورت زیر انجام می‌شود:

پشتیبانی از تابع پنجره توسط فروشندگان RDBMS

پیاده‌سازی قابلیت‌های تابع پنجره‌ای توسط ارائه‌دهندگان پایگاه‌های داده رابطه‌ای و موتورهای SQL تفاوت‌های چشم‌گیری دارد. بیشتر پایگاه‌های داده از نوعی از توابع پنجره‌ای پشتیبانی می‌کنند، اما با بررسی دقیق‌تر مشخص می‌شود که اغلب آن‌ها تنها بخشی از استاندارد را پیاده‌سازی کرده‌اند. برای نمونه، بند قدرتمند RANGE را در نظر بگیرید؛ تنها پایگاه‌های Oracle، DB2، Spark/Hive و Google BigQuery این ویژگی را به‌طور کامل پیاده‌سازی کرده‌اند. در سال‌های اخیر، ارائه‌دهندگان افزونه‌های جدیدی نیز به استاندارد SQL افزوده‌اند، مانند توابع تجمیع آرایه‌ای. این توابع به‌ویژه در زمینه اجرای SQL بر روی سامانه‌های فایل توزیع‌شده (مانند Hadoop، Spark و Google BigQuery) مفید هستند، جایی که تضمین هم‌محلی بودن داده‌ها ضعیف‌تر از پایگاه‌های داده رابطه‌ای توزیع‌شده (MPP) است. به‌جای توزیع یکنواخت داده‌ها میان تمام گره‌ها، موتورهای SQL که بر روی سامانه‌های فایل توزیع‌شده اجرا می‌شوند، می‌توانند با تودرتو کردن داده‌ها از انجام Joinهای پرهزینه و جابجایی سنگین داده‌ها در شبکه جلوگیری کرده و به تضمین هم‌محلی دست یابند. همچنین، توابع تجمیع تعریف‌شده توسط کاربر که می‌توان آن‌ها را در توابع پنجره‌ای به‌کار برد، از دیگر ویژگی‌های بسیار قدرتمند محسوب می‌شوند.

تولید داده در T-SQL

روشی برای تولید داده‌ها بر اساس اتحاد همه

select 1 a, 1 b union all
select 1, 2 union all
select 1, 3 union all
select 2, 1 union all
select 5, 1

SQL Server 2008 از ویژگی "row constructor" که در استاندارد SQL:1999 مشخص شده است، پشتیبانی می‌کند.

select *
from (values (1, 1), (1, 2), (1, 3), (2, 1), (5, 1)) as x(a, b)

منابع


  • پارتیشن‌بندی افقی و عمودی، کتاب‌های آنلاین مایکروسافت SQL Server 2000.

پیوندهای خارجی

[[رده:کلیدواژه‌های SQL]]