تستعرض هذه المقالة بعض معاملات SQL المتخصصة في البحث والتنقيب وترشيح النتائج.
المعامل LIKE
مطابقة الأنماط المفتوحة Match open-ended pattern
يطابق حرف البدل %
الموضوع في بداية أو نهاية السلسلة النصية (أو كليهما) 0 حرف أو أكثر قبل بداية أو بعد نهاية النمط المراد مطابقته.
يسمح استخدام "%' في الوسط بوجود 0 حرف أو أكثر بين جزأي النمط المُراد مُطابقته.
سنستخدم جدول الموظفين Employees
التالي:
Id | FName | LName | PhoneNumber | ManagerId | DepartmentId | Salary | Hire_date |
---|---|---|---|---|---|---|---|
1 | John | Johnson | 2468101214 | 1 | 1 | 400 | 23-03-2005 |
2 | Sophie | Amudsen | 2479100211 | 1 | 1 | 400 | 11-01-2010 |
3 | Ronny | Smith | 2462544026 | 2 | 1 | 600 | 06-08-2015 |
4 | Jon | Sanchez | 2454124602 | 1 | 1 | 400 | 23-03-2005 |
5 | Hilde | Knag | 2468021911 | 2 | 1 | 800 | 01-01-2000 |
تطابق العبارة التالية جميع السجلات التي يحتوي حقل FName
خاصتها على السلسلة النصية 'on':
SELECT * FROM Employees WHERE FName LIKE '%on%';
سنحصل على الخرج التالي:
Id | FName | LName | PhoneNumber | ManagerId | DepartmentId | Salary | Hire_date |
---|---|---|---|---|---|---|---|
3 | Ronny | Smith | 2462544026 | 2 | 1 | 600 | 06-08-2015 |
4 | Jon | Sanchez | 2454124602 | 1 | 1 | 400 | 23-03-2005 |
يطابق التعبير التالي جميع السجلات التي يبدأ الحقل PhoneNumber
خاصتها بالسلسلة النصية "246" في جدول الموظفين.
SELECT * FROM Employees WHERE PhoneNumber LIKE '246%';
سنحصل على الخرج التالي:
Id | FName | LName | PhoneNumber | ManagerId | DepartmentId | Salary | Hire_date |
---|---|---|---|---|---|---|---|
1 | John | Johnson | 2468101214 | 1 | 1 | 400 | 23-03-2005 |
3 | Ronny | Smith | 2462544026 | 2 | 1 | 600 | 06-08-2015 |
5 | Hilde | Knag | 2468021911 | 2 | 1 | 800 | 01-01-2000 |
تطابق العبارة التالية جميع السجلات التي ينتهي الحقل PhoneNumber
خاصتها بالسلسلة النصية "11" في جدول الموظفين.
SELECT * FROM Employees WHERE PhoneNumber LIKE '%11'
Id | FName | LName | PhoneNumber | ManagerId | DepartmentId | Salary | Hire_date |
---|---|---|---|---|---|---|---|
2 | Sophie | Amudsen | 2479100211 | 1 | 1 | 400 | 11-01-2010 |
5 | Hilde | Knag | 2468021911 | 2 | 1 | 800 | 01-01-2000 |
يطابق التعبير التالي جميع السجلات التي يساوي الحرف الثالث من حقل Fname
خاصتها 'n' في جدول الموظفين.
SELECT * FROM Employees WHERE FName LIKE '__n%';
(استخدمنا شرطتين سفليتين قبل 'n' لتخطي أول حرفين)
Id | FName | LName | PhoneNumber | ManagerId | DepartmentId | Salary | Hire_date |
---|---|---|---|---|---|---|---|
3 | Ronny | Smith | 2462544026 | 2 | 1 | 600 | 06-08-2015 |
4 | Jon | Sanchez | 2454124602 | 1 | 1 | 400 | 23-03-2005 |
مطابقة محرف واحد
يمكن استخدام أحرف البدل وعلامة النسبة المئوية (%
) والشرطة السفلية (_
) لتوسيع أنماط الاختيار في SQL.
يمكن استخدام المحرف _
(الشرطة السفلية) كحرف بدل يمثل حرفًا منفردًا.
يبحث النمط التالي عن جميع الموظفين الذين يتألف الحقل Fname
خاصتهم من 3 حروف، ويبدأ بالحرف "j" وينتهي بـ "n".
SELECT * FROM Employees WHERE FName LIKE 'j_n'
يمكن استخدام المحرف _
أكثر من مرة بحيث يتصرف كبطاقة بدل (wild card) لمطابقة أنماط معينة.
على سبيل المثال، يُطابق النمط أعلاه السلاسل النصية التالية: jon
و jan
و jen
. بيْد أنّه لا يُطابق الأسماء التالية: jn
و john
و jordan
و justin
و jason
و julian
و jillian
و joann
، لأنّ الشرطة السفلية التي استخدمناها في الاستعلام تتخطى حرفًا واحدًا فقط، لذلك لن تُقبل إلا الحقول المؤلفة من 3 أحرف.
يُطابق النمط التالي السلاسل النصية التالية: LaSt
و LoSt
و HaLt
:
SELECT * FROM Employees WHERE FName LIKE '_A_T'
العبارة ESCAPE في الاستعلام LIKE
يمكن إجراء بحث نصي في العبارة LIKE
على النحو التالي:
SELECT * FROM T_Whatever WHERE SomeField LIKE CONCAT('%', @in_SearchText, '%')
ستحدث مشكلة إذا أدخل شخص ما نصُّا من قبيل "50%" أو "a_b" (بصرف النظر عن حقيقة أنه يُفضل البحث عن النص الكامل بدل استخدام LIKE
). يمكن حل هذه المشكلة باستخدام عبارة LIKE
:
SELECT * FROM T_Whatever WHERE SomeField LIKE CONCAT('%', @in_SearchText, '%') ESCAPE '\'
هذا يعني أنّ \
ستُعامل كحرف التهريب ESCAPE
. أي أنّه يمكنك الآن إضافة \
إلى كل حرف في السلسلة النصية التي تبحث عنها، وستكون النتائج صحيحة، حتى لو أدخل المستخدم محارف خاصة مثل %
أو _
.
إليك المثال التالي:
string stringToSearch = "abc_def 50%"; string newString = ""; foreach(char c in stringToSearch) newString += @"\" + c; sqlCmd.Parameters.Add("@in_SearchText", newString); // sqlCmd.Parameters.Add("@in_SearchText", stringToSearch); بدلا من
ملاحظة: وضعنا الخوارزمية أعلاه للتوضيح وحسب، ولن تعمل في حال احتوت السلسلة النصية على رسمة (grapheme) مؤلفة من عدّة أحرف (مثل رموز utf-8). مثلًا، في السلسلة النصية string stringToSearch = "Les Mise\u0301rables";
، ستحتاج إلى فعل ذلك لكل رسمة، وليس لكل حرف. عليك ألا تستخدم الخوارزمية أعلاه إذا كنت تتعامل مع لغات آسيوية أو شرق آسيوية أو جنوب آسيوية.
البحث عن مجموعة من المحارف
تطابق العبارة التالية جميع السجلات التي يبدأ حقل FName
خاصتها بحرف محصور (أبجديا) بين A
و F
في جدول الموظفين.
SELECT * FROM Employees WHERE FName LIKE '[A-F]%'
مطابقة نطاق أو مجموعة
يمكن مطابقة حرف واحد داخل نطاق محدد (على سبيل المثال: [a-f]
) أو مجموعة (على سبيل المثال: [abcdef]
).
يطابق نمط النطاق التالي السلسلة النصية gary
، ولكن ليس mary
:
SELECT * FROM Employees WHERE FName LIKE '[a-g]ary'
يُطابق نمط المجموعة التالي mary
ولكن ليس gary
:
SELECT * FROM Employees WHERE Fname LIKE '[lmnop]ary'
يمكن أيضًا عكس أو نفي النطاق أو المجموعة بوضع العلامة ^
قبل النطاق أو المجموعة، فلن يتطابق نمط النطاق التالي مع gary
، ولكنه سيتطابق مع mary
:
SELECT * FROM Employees WHERE FName LIKE '[^a-g]ary'
لن يتطابق نمط المجموعة التالي مع mary
ولكن سيتطابق مع gary
:
SELECT * FROM Employees WHERE Fname LIKE '[^lmnop]ary'
أحرف البدل Wildcard characters
يمكن استخدام أحرف البدل مع المعامل LIKE
. تُستخدم أحرف البدل في SQL للبحث عن البيانات داخل جدول معيّن. وهناك أربعة منها، وهي كالتالي:
- % - بديل عن صفر حرف أو أكثر
-- "Lo" اختيار جميع العملاء الذين يقطنون مدينة تبدأ بـ SELECT * FROM Customers WHERE City LIKE 'Lo%'; -- "es" اختيار جميع العملاء الذين يقطنون مدينة تحتوي SELECT * FROM Customers WHERE City LIKE '%es%';
- _ - بديل عن حرف واحد
-- erlin اختيار جميع العملاء الذين يقطنون مدينة تبدأ بحرف معين، متبوعا بـ SELECT * FROM Customers WHERE City LIKE '_erlin';
- [charlist] - مجموعات ونطاقات مؤلفة من الحروف المُراد مُطابقتها
-- "a" أو "d" أو "l" اختيار جميع العملاء الذين يقطنون مدينة تبدأ بـ SELECT * FROM Customers WHERE City LIKE '[adl]%'; -- "a" أو "d" أو "l" اختيار جميع العملاء الذين يقطنون مدينة تبدأ بـ SELECT * FROM Customers WHERE City LIKE '[a-c]%';
- [^ charlist] - تطابق الحروف غير الموجودة داخل القوسين المربعين
-- "a" أو "d" أو "l" اختيار جميع العملاء الذين يقطنون مدينة لا تبدأ بـ SELECT * FROM Customers WHERE City LIKE '[^apl]%'; or SELECT * FROM Customers WHERE City NOT LIKE '[apl]%' and city like '_%';
التحقق من الانتماء عبر IN
يمكن استخدام العبارة IN للتحقق من إنتماء قيمة إلى مجموعة معينة.
تعيد الشيفرة التالية السجلات التي ينتمي مُعرّفها id
إلى مجموعة معينة من القيم ((1,8,3)):
select * from products where id in (1,8,3)
يكافئ الاستعلام أعلاه:
select * from products where id = 1 or id = 8 or id = 3
يمكن استخدام IN مع استعلام فرعي على النحو التالي:
SELECT * FROM customers WHERE id IN ( SELECT DISTINCT customer_id FROM orders );
ستعيد الشيفرة أعلاه جميع العملاء الذين لديهم طلبات في النظام.
ترشيح النتائج باستخدام WHERE و HAVING
استخدم BETWEEN لترشيح النتائج
تستخدم الأمثلة التالية قاعدتي البيانات Sales
و Customers
.
تذكر أنّ المعامل BETWEEN تضميني (inclusive):
استخدام المعامل BETWEEN مع الأعداد
يعيد الاستعلام التالي جميع سجلات ItemSales
التي ينحصر حقل الكمية quantity
خاصتها بين 10 و 17.
SELECT * From ItemSales WHERE Quantity BETWEEN 10 AND 17
سنحصل على النتائج التالية:
Id | SaleDate | ItemId | Quantity | Price |
---|---|---|---|---|
1 | 2013-07-01 | 100 | 10 | 34.5 |
4 | 2013-07-23 | 100 | 15 | 34.5 |
5 | 2013-07-24 | 145 | 10 | 34.5 |
استخدام المعامل BETWEEN مع قيم التاريخ
يعيد الاستعلام التالي كافة سجلات ItemSales
التي ينحصر حقل SaleDate
خاصتها بين التاريخين 11 يوليو 2013 و 24 مايو 2013.
SELECT * From ItemSales WHERE SaleDate BETWEEN '2013-07-11' AND '2013-05-24'
هذا هو الخرج المتوقع:
Id | SaleDate | ItemId | Quantity | Price |
---|---|---|---|---|
3 | 2013-07-11 | 100 | 20 | 34.5 |
4 | 2013-07-23 | 100 | 15 | 34.5 |
5 | 2013-07-24 | 145 | 10 | 34.5 |
عند موازنة قيم الوقت (datetime) بدلًا من قيم التاريخ (dates)، قد تحتاج إلى تحويل قيم الوقت إلى قيم التاريخ، أو إضافة أو طرح 24 ساعة للحصول على النتيجة المتوقعة.
استخدام المعامل BETWEEN مع القيم النصية
يعيد الاستعلام التالي كافة العملاء الذين تنحصر أسماؤهم (أبجديًا) بين الحرفين 'D' و 'L'. في هذه الحالة، سيُعاد العميلان ذوي الرقمين 1 و 3. أما العميل رقم 2 ، الذي يبدأ اسمه بـالحرف "M"، فلن يُعاد:
SELECT Id, FName, LName FROM Customers WHERE LName BETWEEN 'D' AND 'L';
هذا مثال حي
الخرج:
Id | FName | LName |
---|---|---|
1 | William | Jones |
3 | Richard | Davis |
استخدم HAVING مع الدوال التجميعية
على خلاف العبارة WHERE
، يمكن استخدام HAVING
مع الدوال التجميعية.
الدوال التجميعية (aggregate functions) هي دوال تأخذ القيم الموجودة في في عدة صفوف كمُدخلات (بناء على شروط محددة) وتعيد قيمة معينة. هذه بعض الدوال التجميعية: COUNT()
و SUM()
و MIN()
و MAX()
.
يستخدم هذا المثال الجدول Car
من الفصل الأول.
SELECT CustomerId, COUNT(Id) AS [Number of Cars] FROM Cars GROUP BY CustomerId HAVING COUNT(Id) > 1
يعيد الاستعلام أعلاه CustomerId
وعدد السيارات Number of Cars
لأيّ عميل لديه أكثر من سيارة واحدة. في هذا المثال، العميل الوحيد الذي لديه أكثر من سيارة واحدة هو العميل رقم 1.
هذا هو الخرج:
CustomerId | Number of Cars |
---|---|
1 | 2 |
استخدام WHERE مع القيم NULL / NOT NULL
يعيد المثال التالي جميع سجلات الموظفين (Employee) التي تتساوى قيمة العمود ManagerId
خاصتهم مع القيمة المعدومة NULL
.
SELECT * FROM Employees WHERE ManagerId IS NULL
النتيجة:
Id FName LName PhoneNumber ManagerId DepartmentId 1 James Smith 1234567890 NULL 1
يعيد المثال التالي جميع سجلات الموظفين التي لا تساوي قيمة العمود ManagerId
خاصتهم القيمة NULL
.
SELECT * FROM Employees WHERE ManagerId IS NOT NULL
ستكون النتيجة كما يلي:
Id FName LName PhoneNumber ManagerId DepartmentId 2 John Johnson 2468101214 1 1 3 Michael Williams 1357911131 1 2 4 Johnathon Smith 1212121212 2 1
ملاحظة: لن يعيد الاستعلام أعلاه أيّ نتائج في حال غيّرت صياغة العبارة WHERE إلى WHERE ManagerId = NULL
أو WHERE ManagerId <> NULL
.
معامل التساوي
تعيد الشيفرة التالية كل صفوف الجدول Employees
.
SELECT * FROM Employees
الخرج:
Id FName LName PhoneNumber ManagerId DepartmentId Salary Hire_date CreatedDate ModifiedDate 1 James Smith 1234567890 NULL 1 1000 01-01-2002 01-01-2002 01-01-2002 2 John Johnson 2468101214 1 1 400 23-03-2005 23-03-2005 01-01-2002 3 Michael Williams 1357911131 1 2 600 12-05-2009 12-05-2009 NULL 4 Johnathon Smith 1212121212 2 1 500 24-07-2016 24-07-2016 01-01-2002
يتيح لك استخدام WHERE
في نهاية العبارة SELECT
ترشيح الصفوف المُعادة وفق شرط معين. إن أردت مثلًا اشتراط التطابق التام مع قيمة معينة، فاستخدم علامة التساوي =
:
SELECT * FROM Employees WHERE DepartmentId = 1
لن يعيد الاستعلام أعلاه إلا الصفوف التي يساوي الحقل DepartmentId
خاصتها القيمة 1
:
Id FName LName PhoneNumber ManagerId DepartmentId Salary Hire_date CreatedDate ModifiedDate 1 James Smith 1234567890 NULL 1 1000 01-01-2002 01-01-2002 01-01-2002 2 John Johnson 2468101214 1 1 400 23-03-2005 23-03-2005 01-01-2002 4 Johnathon Smith 1212121212 2 1 500 24-07-2016 24-07-2016 01-01-2002
لنفترض أنّ متجرًا للألعاب لديه فئة من الألعاب يقل سعرها عن 10 دولارات. يعيد الاستعلام التالي هذه الفئة من الألعاب:
SELECT * FROM Items WHERE Price < 10
المعاملان المنطقيان AND و OR
يمكنك الجمع بين عدة معاملات معًا لإنشاء شروط WHERE
أكثر تعقيدًا.
تستخدم الأمثلة التالية الجدول Employees
التالي:
Id FName LName PhoneNumber ManagerId DepartmentId Salary Hire_date CreatedDate ModifiedDate 1 James Smith 1234567890 NULL 1 1000 01-01-2002 01-01-2002 01-01-2002 2 John Johnson 2468101214 1 1 400 23-03-2005 23-03-2005 01-01-2002 3 Michael Williams 1357911131 1 2 600 12-05-2009 12-05-2009 NULL 4 Johnathon Smith 1212121212 2 1 500 24-07-2016 24-07-2016 01-01-2002
إليك الاستعلام التالي:
SELECT * FROM Employees WHERE DepartmentId = 1 AND ManagerId = 1
سينتج الخرج التالي:
Id FName LName PhoneNumber ManagerId DepartmentId Salary Hire_date CreatedDate ModifiedDate 2 John Johnson 2468101214 1 1 400 23-03-2005 23-03-2005 01-01-2002
وهذا استعلام آخر يستخدم المعامل المنطقي OR:
SELECT * FROM Employees WHERE DepartmentId = 2 OR ManagerId = 2
سينتج الخرج التالي:
Id FName LName PhoneNumber ManagerId DepartmentId Salary Hire_date CreatedDate ModifiedDate 3 Michael Williams 1357911131 1 2 600 12-05-2009 12-05-2009 NULL 4 Johnathon Smith 1212121212 2 1 500 24-07-2016 24-07-2016 01-01-2002
استخدم IN لإعادة الصفوف التي تنتمي قيمها إلى قائمة معينة
يستخدم هذا المثال الجدول "Car".
SELECT * FROM Cars WHERE TotalCost IN (100, 200, 300)
سيعيد هذا الاستعلام السيارة رقم 2، والتي تبلغ تكلفتها 200، والسيّارة رقم 3، والتي تساوي تكلفتها 100. لاحظ أنّ الاستعلام أعلاه يكافئ استخدام OR
عدة مرّات كما هو موضّح في المثال التالي:
SELECT * FROM Cars WHERE TotalCost = 100 OR TotalCost = 200 OR TotalCost = 300
استخدم LIKE للبحث عن السلاسل النصية
يستخدم المثال التالي الجدول Car:
SELECT * FROM Employees WHERE FName LIKE 'John'
لن يعيد هذا الاستعلام إلا الموظف رقم 1، والذي يتطابق اسمه الأول مع السلسلة النصية "John".
SELECT * FROM Employees WHERE FName like 'John%'
يمكنك البحث عن سلسلة نصية فرعية عبر إضافة الرمز %
:
-
John%
- تعيد أيّ موظف يبدأ اسمه بـ "John" ، متبوعًا بأي عدد من الأحرف -
%John
- تعيد أيّ موظف ينتهي اسمه بـ "John" ، يعقبه أي عدد من الأحرف -
%John%
- تعيد أيّ موظف يتضمّن اسمه السلسلة النصية "John"
في المثال أعلاه، سيعيد الاستعلام الموظفَ رقم 2، والذي يحمل الاسم "John"، وكذلك الموظف رقم 4، والذي يحمل الاسم "Johnathon".
Where EXISTS
في المثال التالي، تختار العبارة WHERE EXISTS
سجلّات TableName
التي تطابق سجلاتٍ في الجدول TableName1
.
SELECT * FROM TableName t WHERE EXISTS ( SELECT 1 FROM TableName1 t1 where t.Id = t1.Id)
استخدام HAVING للتحقق من عدة شروط
إليك جدول الطلبات التالي:
CustomerId | ProductId | Quantity | Price |
---|---|---|---|
1 | 2 | 5 | 100 |
1 | 3 | 2 | 200 |
1 | 4 | 1 | 500 |
2 | 1 | 4 | 50 |
3 | 5 | 6 | 700 |
للحصول على العملاء الذين طلبوا المنتَجَين ذوي المُعرّف 2 و 3، يمكن استخدام العبارة HAVING:
select customerId from orders where productID in (2,3) group by customerId having count(distinct productID) = 2
الخرج الناتج:
customerId |
---|
1 |
لن يختار الاستعلام إلا السجلات ذات معرّفات المنتجات المحددة، والتي تحقق شرط HAVING
، أي وجود معرّفين اثنين للمنتجات (productIds)، وليس معرّفًا واحدًا فقط.
هذه صياغة أخرى:
select customerId from orders group by customerId having sum(case when productID = 2 then 1 else 0 end) > 0 and sum(case when productID = 3 then 1 else 0 end) > 0
لن يختار هذا الاستعلام إلا المجموعات التي لها سجل واحد على الأقل يساوي معرّف منتجه (productID) القيمة 2، وسجل واحد على الأقل يساوي معرّف منتجه 3.
ترقيم الصفحات Pagination
يمكن وضع حدّ لعدد النتائج المُعادة في استعلام معين، لكنّ الصياغة تختلف بحسب النظام المُستخدم:
- في إصدار SQL القياسي ISO / ANSI:
SELECT * FROM TableName FETCH FIRST 20 ROWS ONLY;
- MySQL و PostgreSQL و SQLite:
SELECT * FROM TableName LIMIT 20;
- Oracle :
SELECT Id, Col1 FROM (SELECT Id, Col1, row_number() over (order by Id) RowNumber FROM TableName) WHERE RowNumber <= 20
- SQL Server:
SELECT TOP 20 * FROM dbo.[Sale]
قد ترغب أحيانًا في تخطّي عدد من نتائج الاستعلام وتأخذ النتائج الموالية لها، يمكنك ذلك عبر الصياغة التالية:
- ISO / ANSI SQL:
SELECT Id, Col1 FROM TableName ORDER BY Id OFFSET 20 ROWS FETCH NEXT 20 ROWS ONLY;
- MySQL:
SELECT * FROM TableName LIMIT 20, 20; -- offset, limit
- Oracle و SQL Server:
SELECT Id, Col1 FROM (SELECT Id, Col1, row_number() over (order by Id) RowNumber FROM TableName) WHERE RowNumber BETWEEN 21 AND 40
- PostgreSQL و SQLite:
SELECT * FROM TableName LIMIT 20 OFFSET 20;
يمكنك كذلك تخطي بعض الصفوف من نتائج الاستعلام على النحو التالي:
- ISO / ANSI SQL:
SELECT Id, Col1 FROM TableName ORDER BY Id OFFSET 20 ROWS
- MySQL:
SELECT * FROM TableName LIMIT 20, 42424242424242; -- تخطي 20 صفا، بالنسبة لعدد الصفوف المأخوذة، استخدم عددا كبيرا يتجاوز عدد الصفوف في الجدول
- Oracle:
SELECT Id, Col1 FROM (SELECT Id, Col1, row_number() over (order by Id) RowNumber FROM TableName) WHERE RowNumber > 20
- PostgreSQL:
SELECT * FROM TableName OFFSET 20;
- SQLite:
SELECT * FROM TableName LIMIT -1 OFFSET 20;
EXCEPT
يمكنك استثناء مجموعة من البيانات عبر استخدام الكلمة المفتاحية EXCEPT
.
إليك المثال التالي:
-- ينبغي أن تكون مجموعات البيانات متماثلة SELECT 'Data1' as 'Column' UNION ALL SELECT 'Data2' as 'Column' UNION ALL SELECT 'Data3' as 'Column' UNION ALL SELECT 'Data4' as 'Column' UNION ALL SELECT 'Data5' as 'Column' EXCEPT SELECT 'Data3' as 'Column' -- ==> Data1 و Data2 و Data4 و Data5
EXPLAIN و DESCRIBE
استعمال EXPLAIN في استعلامات الاختيار
عند وضع Explain
قُبالة استعلام select
، سيعرض محرّك قاعدة البيانات بعض البيانات التي توضّح كيفية تنفيذ الاستعلام. يمكنك استخدام هذه البيانات لفهم الشيفرة ومن ثَمَّ تحسينها، مثلًا، لو لاحظت أنّ الاستعلام لا يستخدم فهرسًا، فيمكنك تحسين استعلامك عن طريق إضافة فهرس.
إليك الاستعلام التالي:
explain select * from user join data on user.test = data.fk_user;
سنحصل على الخرج التالي:
id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE user index test test 5 (null) 1 Using where; Using index 1 SIMPLE data ref fk_user fk_user 5 user.tes t 1 (null)
يحدد العمود type
ما إذا كان الاستعلام يستخدم الفهرس أم لا. وفي العمود possible_keys
، سترى ما إذا كان بالإمكان تنفيذ الاستعلام بواسطة فهارس أخرى إن لم يتوافر الفهرس. يعرض key
الفهرس المستخدم، فيما يعرض العمود key_len
حجم عنصر من الفهرس (بالبايتات bytes)، وكلما انخفضت هذه القيمة، زاد عدد عناصر الفهرس التي يمكن تخزينها في مساحة معينة من الذاكرة، وهو ما يسرّع معالجتها. يعرض العمود rows
العدد المتوقع للصفوف التي يحتاج الاستعلام إلى جردها، كلما كان هذا العدد أصغر، كان الأداء أفضل.
DESCRIBE tablename
DESCRIBE
و EXPLAIN متماثلتان، بيد أنّ DESCRIBE
تعيد معلومات تعريفية لأعمدة الجدول tablename:
DESCRIBE tablename;
النتيجة:
COLUMN_NAME COLUMN_TYPE IS_NULLABLE COLUMN_KEY COLUMN_DEFAULT EXTRA id int(11) NO PRI 0 auto_increment test varchar(255) YES (null)
عُرِضت أسماء الأعمدة متبوعة بنوعها، إضافة إلى توضيح ما إذا كان من الممكن استخدام null
في العمود، وما إذا كان العمود يستخدم فهرسًا. تُعرض أيضًا القيمة الافتراضية للعمود، وما إذا كان الجدول ينطوي على أّي سلوك خاص، مثل auto_increment
.
العبارة EXISTS
إليك جدول العملاء التالي:
Id | FirstName | LastName |
---|---|---|
1 | Ozgur | Ozturk |
2 | Youssef | Medi |
3 | Henry | Tai |
وهذا جدول آخر للطلبيّات:
Id | CustomerId | Amount |
---|---|---|
1 | 2 | 123.50 |
2 | 3 | 14.80 |
تعيد هذه الشيفرة جميع العملاء الذين قدموا طلبية واحدة على الأقل:
SELECT * FROM Customer WHERE EXISTS ( SELECT * FROM Order WHERE Order.CustomerId=Customer.Id )
النتيجة المتوقعة:
Id | FirstName | LastName |
---|---|---|
2 | Youssef | Medi |
3 | Henry | Tai |
يعيد الاستعلام التالي جميع العملاء الذين لم يقدّمو أيّ طلبية:
SELECT * FROM Customer WHERE NOT EXISTS ( SELECT * FROM Order WHERE Order.CustomerId = Customer.Id )
النتيجة المتوقّعة:
Id | FirstName | LastName |
---|---|---|
1 | Ozgur | Ozturk |
تُستخدم EXISTS
و IN
و JOIN
أحيانًا للحصول على النتائج نفسها، بيْد أنّ هناك اختلافات في كيفية عملها:
-
تُستخدم
EXISTS
للتحقق من وجود قيمة في جدول آخر. -
تُستخدم
IN
للحصول على قائمة ثابتة. -
تُستخدم
JOIN
لاسترجاع البيانات من جداول أخرى.
ترجمة -وبتصرّف- للفصول من 11 إلى 17 من الكتاب SQL Notes for Professionals
اقرأ أيضًا:
- المقال التالي: الدمج بين الجداول في SQL
- المقال السابق: تنفيذ تعليمات شرطية عبر CASE في SQL
- النسخة العربية الكاملة من كتاب ملاحظات للعاملين بلغة SQL 1.0.0
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.