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;
- ↑ Microsoft (23 May 2023). "Transact-SQL Syntax Conventions".
- ↑ 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" | پرسوجو | نتیجه | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
SELECT * FROM T;
|
| ||||||||||||
|
SELECT C1 FROM T;
|
| ||||||||||||
|
SELECT * FROM T WHERE C1 = 1;
|
| ||||||||||||
|
SELECT * FROM T ORDER BY C1 DESC;
|
| ||||||||||||
وجود ندارد | SELECT 1+1, 3*2;
|
|
با فرض وجود جدولی به نام 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 ، مجموعه نتایج ممکن است با استفاده از موارد زیر محدود شوند:
- مکاننماها ، یا
- با اضافه کردن یک تابع پنجره SQL به دستور SELECT
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) * ردیفها
سادهترین روش (اما بسیار ناکارآمد)
- انتخاب تمام سطرها از پایگاه داده
- همه ردیفها را میخواند اما فقط زمانی نمایش میدهد که شماره ردیف ردیفهای خوانده شده بین
{begin_base_0 + 1}
و{begin_base_0 + rows}
باشد.Select * from {table} order by {unique_key}
sum(population) OVER( PARTITION BY city )
روش ساده دیگر (کمی کارآمدتر از خواندن همه ردیفها)
- تمام ردیفها را از ابتدای جدول تا آخرین ردیف برای نمایش انتخاب میکند (
{begin_base_0 + rows}
) - سطرهای
{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 |
روش با موقعیت یابی
- فقط
{rows}
ردیفهایی را که از ردیف بعدی برای نمایش شروع میشوند، انتخاب کنید ({begin_base_0 + 1}
) - خواندن و ارسال برای نمایش تمام ردیفهای خوانده شده از پایگاه داده
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 |
روش با فیلتر (پیچیدهتر است اما برای مجموعه دادههای بسیار بزرگ ضروری است)
- فقط ردیفهای
{rows}
را با فیلتر انتخاب کنید:- صفحه اول: فقط سطرهای اول
{rows}
را انتخاب کنید، بسته به نوع پایگاه داده - صفحه بعد: فقط اولین
{rows}
سطرها را انتخاب کنید، بسته به نوع پایگاه داده، که در آن{unique_key}
بزرگتر از{last_val}
(مقدار{unique_key}
آخرین سطر در صفحه فعلی) باشد. - صفحه قبل: دادهها را به ترتیب معکوس مرتب کنید، فقط اولین
{rows}
ردیفها را انتخاب کنید، که در آن{unique_key}
کمتر از{first_val}
(مقدار{unique_key}
ردیف اول در صفحه فعلی) باشد، و نتیجه را به ترتیب صحیح مرتب کنید.
- صفحه اول: فقط سطرهای اول
- خواندن و ارسال برای نمایش تمام ردیفهای خوانده شده از پایگاه داده
صفحهی اول | صفحهی بعدی | صفحهی قبلی |
---|---|---|
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 ، استفان دِسلوخ
- نحو SELECT در اوراکل
- سینتکس SELECT در فایربرد
- نحو انتخاب MySQL
- نحو انتخاب PostgreSQL
- نحو SELECT در SQLite
[[رده:کلیدواژههای SQL]]