یکی از بنیادیترین بخشهای کار با دیتابیسها، بازیابی اطلاعات مربوط به دادههای ذخیرهشده در آنهاست. در سیستمهای مدیریت دیتابیس رابطهای، هر عملیاتی که برای بازیابی اطلاعات از یک جدول انجام شود، کوئری نامیده میشود.
در این راهنما، درباره سینتکس کوئریها در Structured Query Language (SQL) و برخی توابع و عملگرهای پرکاربرد آن صحبت خواهیم کرد.
برای دنبال کردن این راهنما، به یک کامپیوتر با سیستم مدیریت دیتابیس رابطهای (RDBMS) نیاز دارید که از SQL پشتیبانی کند. دستورها و مثالهای این راهنما با محیط زیر تست شدهاند:
توجه: بسیاری از RDBMSها، پیادهسازی اختصاصی خودشان را از SQL دارند. با وجود اینکه دستورهای این آموزش روی اکثر RDBMSها کار میکند، ممکن است سینتکس یا خروجی دقیق آنها بسته به سیستم شما متفاوت باشد.
اگر دیتابیس SQL شما روی سرور ریموت اجرا میشود، ابتدا با SSH از سیستم محلی به سرور متصل شوید:
ssh sammy@your_server_ip
سپس پنجره MySQL server را باز کنید و به جای sammy نام کاربری MySQL خودتان را قرار دهید:
mysql -u sammy -p
از این پنجره، دیتابیسی با نام queries_db بسازید:
CREATE DATABASE queries_db;
اگر دیتابیس با موفقیت ساخته شده باشد، خروجی مشابه زیر دریافت میکنید:
Output
Query OK, 1 row affected (0.01 sec)
برای انتخاب دیتابیس queries_db، دستور زیر را اجرا کنید:
USE queries_db;
Output
Database changed
بعد از انتخاب queries_db، چند جدول داخلش بسازید.
برای دنبال کردن مثالهای این راهنما، فرض کنید یک برنامه جمعآوری زباله در پارکهای عمومی نیویورک اجرا میکنید. این برنامه شامل داوطلبانی است که متعهد شدهاند پارکهای نزدیک منزلشان را به طور منظم تمیز کنند. هر داوطلب هنگام پیوستن به برنامه، هدف تعداد کیسههای زبالهای که هر هفته جمعآوری خواهد کرد را تعیین میکند. شما تصمیم میگیرید اطلاعات مربوط به اهداف داوطلبان را در یک دیتابیس SQL با جدولی شامل پنج ستون ذخیره کنید:
دستور CREATE TABLE زیر را اجرا کنید تا جدول volunteers با پنج ستون ایجاد شود:
CREATE TABLE volunteers (
vol_id int UNIQUE,
name varchar(20),
park varchar(30),
weekly_goal int,
max_bags int,
PRIMARY KEY (vol_id)
);
سپس با دستور INSERT INTO هفت ردیف دادهی نمونه را به جدول وارد کنید که معرف هفت داوطلب برنامه باشند:
INSERT INTO volunteers
VALUES
(1, 'Gladys', 'Prospect Park', 3, 5),
(2, 'Catherine', 'Central Park', 2, 2),
(3, 'Georgeanna', 'Central Park', 2, 1),
(4, 'Wanda', 'Van Cortland Park', 1, 1),
(5, 'Ann', 'Prospect Park', 2, 7),
(6, 'Juanita', 'Riverside Park', 1, 4),
(7, 'Georgia', 'Prospect Park', 1, 3);
حالا آمادهاید ادامه راهنما را دنبال کنید و یاد بگیرید چگونه کوئریهای SQL بنویسید.
در SQL، یک statement هر عملیاتی است که به سیستم دیتابیس ارسال شده تا کاری انجام دهد؛ مانند ایجاد جدول، وارد کردن یا حذف داده یا تغییر ساختار ستون یا جدول. کوئری، یک statement در SQL است که اطلاعاتی درباره دادههای ذخیرهشده در دیتابیس بازیابی میکند.
خود کوئری هیچ تغییری در دادههای موجود جدول ایجاد نمیکند. فقط اطلاعاتی را که نویسنده کوئری به طور صریح درخواست کرده، باز میگرداند. اطلاعات برگشتی توسط یک کوئری را result set مینامند. result set معمولاً شامل یک یا چند ستون از جدول مشخصشده است و هر ستون میتواند یک یا چند ردیف اطلاعات داشته باشد.
سینتکس کلی یک کوئری SQL به این صورت است:
SELECT columns_to_return
FROM table_to_query;
دستورات SQL از اجزای مختلفی به نام clause تشکیل میشوند که شامل کلمه کلیدی و اطلاعات موردنیاز آن هستند. حداقل، یک کوئری به دو clause نیاز دارد: SELECT و FROM.
توجه: در این مثال، هر clause در خط جداگانه نوشته شده است. اما هر دستور SQL را میتوان روی یک خط نوشت، مانند:
SELECT columns_to_return FROM table_to_query;
این راهنما از convention رایج SQL که جملات را جداگانه و در خطوط مجزا قرار میدهد پیروی میکند تا مثالها خواناتر شوند، اما تا زمانی که خطاهای سینتکسی نداشته باشید، میتوانید هر کوئری را یک خطی یا چند خطی بنویسید.
هر کوئری SQL با کلمه SELECT شروع میشود و برخی افراد به کوئریها اصطلاحاً SELECT statement نیز میگویند. بعد از SELECT، لیست ستونهایی است که میخواهید در result set برگردد. این ستونها از جدولی که در clause FROM مشخص شده است برداشت میشوند.
در کوئریهای SQL، ترتیب اجرا ابتدا با clause FROM آغاز میشود. این ممکن است گیجکننده باشد، چون SELECT قبل از FROM نوشته میشود، اما RDBMS باید ابتدا مجموعه دادههایی را که کوئری قرار است انجام شود مشخص کند، سپس شروع به بازیابی اطلاعات کند. میتوانید همین را اینطور تصور کنید: ستونهای مشخصشده را از جدول خاصی انتخاب میکنیم. همچنین، هر statement باید با سیمیکالن (;) تمام شود.
مثلاً کوئری زیر را اجرا کنید تا ستون name را از جدول volunteers دریافت کنید:
SELECT name
FROM volunteers;
result set این کوئری به صورت زیر خواهد بود:
Output
+------------+
| name |
+------------+
| Gladys |
| Catherine |
| Georgeanna |
| Wanda |
| Ann |
| Juanita |
| Georgia |
+------------+
7 rows in set (0.00 sec)
با اینکه این عملیات کل جدول volunteers را بررسی کرد، فقط ستون name را برمیگرداند.
میتوانید اطلاعات چند ستون را با کاما جدا کنید. دستور زیر ستونهای vol_id، name و park را از جدول volunteers برمیگرداند:
SELECT park, name, vol_id
FROM volunteers;
Output
+-------------------+------------+--------+
| park | name | vol_id |
+-------------------+------------+--------+
| Prospect Park | Gladys | 1 |
| Central Park | Catherine | 2 |
| Central Park | Georgeanna | 3 |
| Van Cortland Park | Wanda | 4 |
| Prospect Park | Ann | 5 |
| Riverside Park | Juanita | 6 |
| Prospect Park | Georgia | 7 |
+-------------------+------------+--------+
7 rows in set (0.00 sec)
دقت کنید ستونهای result set به همان ترتیبی که در clause SELECT آمدهاند قرار میگیرند.
گاهی میخواهید همه ستونهای جدول را دریافت کنید. به جای نوشتن همه نامها، میتوانید از ستاره (*) استفاده کنید که در SQL معادل “تمام ستونها” است.
SELECT *
FROM volunteers;
Output
+--------+------------+-------------------+-------------+----------+
| vol_id | name | park | weekly_goal | max_bags |
+--------+------------+-------------------+-------------+----------+
| 1 | Gladys | Prospect Park | 3 | 5 |
| 2 | Catherine | Central Park | 2 | 2 |
| 3 | Georgeanna | Central Park | 2 | 1 |
| 4 | Wanda | Van Cortland Park | 1 | 1 |
| 5 | Ann | Prospect Park | 2 | 7 |
| 6 | Juanita | Riverside Park | 1 | 4 |
| 7 | Georgia | Prospect Park | 1 | 3 |
+--------+------------+-------------------+-------------+----------+
7 rows in set (0.00 sec)
ستونهای result set به همان ترتیبی که در دستور CREATE TABLE تعریف شدهاند قرار میگیرند. معمولاً اگر در SELECT به جای نام ستونها از * استفاده کنید، ستونها به همین ترتیب برمیگردند.
میتوانید اطلاعات چند جدول را در یک کوئری با کلیدواژه JOIN دریافت کنید. پیشنهاد میکنیم راهنمای “استفاده از JOIN در SQL” را مطالعه نمایید.
به طور پیشفرض، RDBMS همه مقادیر یک ستون را برمیگرداند، حتی مقادیر تکراری.
مثلاً کوئری زیر فقط مقادیر ستون park جدول volunteers را برمیگرداند:
SELECT park
FROM volunteers;
Output
+-------------------+
| park |
+-------------------+
| Prospect Park |
| Central Park |
| Central Park |
| Van Cortland Park |
| Prospect Park |
| Riverside Park |
| Prospect Park |
+-------------------+
7 rows in set (0.00 sec)
در result set مقادیری مثل Prospect Park و Central Park چند بار تکرار شدهاند، چون چند داوطلب در یک پارک مشغولاند. اما گاهی فقط میخواهید مقادیر منحصربهفرد ستون را بدانید. میتوانید بعد از SELECT از DISTINCT استفاده کنید.
در این کوئری، سه ردیف کمتر از قبلی برگشت داده میشود، زیرا مقدارهای تکراری Central Park و Prospect Park حذف شدهاند.
SQL هر ردیف در result set را رکورد جداگانه میداند و DISTINCT فقط ردیفهایی را حذف میکند که همه ستونهایشان کاملاً مشابه باشند.
برای مثال، کوئری زیر DISTINCT را با دو ستون name و park اجرا میکند:
SELECT DISTINCT name, park
FROM volunteers;
Output
+------------+-------------------+
| name | park |
+------------+-------------------+
| Gladys | Prospect Park |
| Catherine | Central Park |
| Georgeanna | Central Park |
| Wanda | Van Cortland Park |
| Ann | Prospect Park |
| Juanita | Riverside Park |
| Georgia | Prospect Park |
+------------+-------------------+
7 rows in set (0.00 sec)
در این نتیجه با اینکه park چند بار تکرار شده، چون nameها متفاوت است هیچ ردیفی حذف نمیشود.
گاهی میخواهید اطلاعات دقیقتر را دریافت کنید. میتوانید با WHERE برخی ردیفها را فیلتر کنید:
SELECT columns_to_return
FROM table_to_query
WHERE search_condition;
بعد از WHERE، یک شرط جستجو میآید که مشخص میکند چه ردیفهایی فیلتر شوند. این شرط حاوی یک یا چند predicate است (عبارتی که یک یا چند مقدار را میسنجد). در SQL به این مقدارها value expression گفته میشود، که ممکن است مقدار عددی یا رشتهای یا نام ستون باشد.
predicateها معمولاً به این صورت هستند:
. . .
WHERE value expression OPERATOR value_expression
. . .
بعد از WHERE نام ستون میآید و سپس یکی از عملگرهای خاص SQL که مقدار ستون را با مقدار مشخص شده مقایسه میکند. این راهنما فعلاً روی یکی از رایجترین عملگرها یعنی علامت مساوی (=) تمرکز میکند که ارزیابی میکند دو عبارت برابرند یا نه.
predicate همیشه یکی از نتیجههای “true”، “false” یا “unknown” را دارد. وقتی کوئری SQL با WHERE اجرا میکنید، DBMS شرط جستجو را به طور ترتیبی روی هر ردیف جدول FROM اعمال میکند. فقط ردیفهایی که predicate آنها “true” شود برگشت داده میشوند.
برای مثال، کوئری زیر از جدول volunteers ستون name را انتخاب میکند اما WHERE بررسی میکند که آیا (2 + 2) با 4 برابر است:
SELECT name
FROM volunteers
WHERE (2 + 2) = 4;
چون (2 + 2) همیشه برابر با 4 است، این شرط برای همه ردیفها “true” میشود و تمام مقادیر name برگشت داده میشوند:
Output
+------------+
| name |
+------------+
| Gladys |
| Catherine |
| Georgeanna |
| Wanda |
| Ann |
| Juanita |
| Georgia |
+------------+
7 rows in set (0.00 sec)
این شرط جستجو عملاً فایدهای ندارد و مشابه SELECT name FROM volunteers; است.
به جای مقایسه دو مقدار ثابت، معمولاً از نام ستون به عنوان value expression در WHERE استفاده میشود تا DBMS مقدارِ هر ردیف را ارزیابی کند.
کوئری زیر name و max_bags را برای ردیفهایی که مقدار max_bags آنها برابر ۴ است برمیگرداند:
SELECT name, max_bags
FROM volunteers
WHERE max_bags = 4;
فقط یک داوطلب max_bags برابر ۴ دارد، پس فقط اطلاعات همان داوطلب برگشت داده میشود:
Output
+---------+----------+
| name | max_bags |
+---------+----------+
| Juanita | 4 |
+---------+----------+
1 row in set (0.00 sec)
همچنین میتوانید مقادیر رشتهای را بررسی کنید. کوئری زیر vol_id و name را برای ردیفهایی که name برابر ‘Wanda’ است برمیگرداند:
SELECT vol_id, name
FROM volunteers
WHERE name = 'Wanda';
چون فقط یک داوطلب به نام Wanda داریم، فقط اطلاعات همان ردیف برگشت داده میشود:
Output
+--------+-------+
| vol_id | name |
+--------+-------+
| 4 | Wanda |
+--------+-------+
1 row in set (0.00 sec)
همانطور که دیدید، در همه مثالها از عملگر مساوی استفاده شد. اما انواع دیگری از عملگرها هم وجود دارند که کنترل بیشتری روی اطلاعات برگشتی کوئریها به شما میدهند.
استاندارد SQL شامل ۱۸ نوع predicate است، اما همه آنها در هر RDBMS وجود ندارند. پنج مورد رایج عبارتند از:
- مقایسه (Comparison): ۶ عملگر مقایسه عبارتند از <, >, <=, >=, =, <>
- Null: عملگر IS NULL برای بررسی مقدارهای Null
- Range: عملگر BETWEEN برای سنجش آیا مقدار ستون بین دو مقدار دیگر قرار میگیرد
- Membership: عملگر IN برای بررسی عضویت مقدار در مجموعهای از مقدارها
- Pattern Match: عملگر LIKE برای مطابقت با الگوهای رشتهای و wildcardها
توضیح بیشتر دربارهی هر predicate فراتر از این راهنماست. اگر مایل به یادگیری بیشتر هستید، پیشنهاد میکنیم مقاله “استفاده از WHERE در SQL” را مطالعه کنید.
گاهی نتیجه کوئری به شکل مورد نیاز شما نیست. میتوانید با دستور ORDER BY نتیجه را مرتب کنید.
SELECT columns_to_return
FROM table_to_query
ORDER BY column_name;
مثلاً برای یافتن داوطلب با بیشترین مقدار max_bags، کوئری زیر را اجرا کنید:
SELECT name, max_bags
FROM volunteers;
اما نتیجه به ترتیب ورود دادههاست:
Output
+------------+----------+
| name | max_bags |
+------------+----------+
| Gladys | 5 |
| Catherine | 2 |
| Georgeanna | 1 |
| Wanda | 1 |
| Ann | 7 |
| Juanita | 4 |
| Georgia | 3 |
+------------+----------+
7 rows in set (0.00 sec)
اگر جدول بزرگی داشته باشید، پیدا کردن بیشترین مقدار به این روش سخت میشود.
میتوانید همان کوئری را با ORDER BY اجرا کنید تا نتیجه بر اساس ستون max_bags مرتب شود:
SELECT name, max_bags
FROM volunteers
ORDER BY max_bags;
Output
+------------+----------+
| name | max_bags |
+------------+----------+
| Georgeanna | 1 |
| Wanda | 1 |
| Catherine | 2 |
| Georgia | 3 |
| Juanita | 4 |
| Gladys | 5 |
| Ann | 7 |
+------------+----------+
7 rows in set (0.00 sec)
در حالت پیشفرض، کوئری با ORDER BY مقادیر ستون را به صورت صعودی (از کم به زیاد) مرتب میکند. برای مرتبسازی نزولی، کلیدواژه DESC را اضافه کنید:
SELECT name, max_bags
FROM volunteers
ORDER BY max_bags DESC;
Output
+------------+----------+
| name | max_bags |
+------------+----------+
| Ann | 7 |
| Gladys | 5 |
| Juanita | 4 |
| Georgia | 3 |
| Catherine | 2 |
| Georgeanna | 1 |
| Wanda | 1 |
+------------+----------+
7 rows in set (0.00 sec)
در این راهنما یاد گرفتید چطور کوئری ساده بنویسید و نتیجه کوئری را فیلتر یا مرتبسازی کنید. اگرچه این دستورها روی اکثر دیتابیسهای رابطهای کار میکند، اما به یاد داشته باشید هر دیتابیس SQL پیادهسازی خاص خودش را دارد. برای شرح کامل هر دستور و همه گزینهها، به مستندات رسمی DBMS خودتان مراجعه کنید.
Structured Query Language—معروف به SQL—زبانی برای تعریف، کنترل، مدیریت و کوئری دادههای ذخیرهشده در دیتابیس رابطهای است. SQL از دهه ۱۹۷۰ تاکنون به طور گستردهای مورد استفاده قرار گرفته و امروز زبان غالب مدیریت دیتابیسهای رابطهای است.
SQL برای مدیریت دادههای ساختارمند (دادههایی که به راحتی در مدل دادهای موجود قرار میگیرند) بسیار ایدهآل است و ابزار ضروری برای توسعهدهندگان و مدیران سیستم در زمینههای متعدد محسوب میشود. همچنین به دلیل عمق و گسترش استفاده از SQL، کسانی که تجربه کار با آن دارند در بسیاری از صنایع پرتقاضا هستند.
این سری آموزشی برای شروع کار با SQL نوشته شده و شامل ترکیبی از مقالات مفهومی و آموزشی مقدماتی درباره موضوعات و تمرینهای مختلف SQL است. همچنین میتوانید هنگام شکلدادن مهارتهای خود از مطالب این سری به عنوان مرجع استفاده کنید.
توجه: مثالهای این آموزشها با MySQL نوشته شدهاند، با این حال اکثر سیستمهای دیتابیس رابطهای پیادهسازی خاص خود از SQL را دارند و ممکن است دستورها یا خروجی آنها کمی متفاوت باشد.
از همراهی شما با پارمین کلود متشکریم.
نظرات کاربران