SQL للمطورين ومحللي البيانات

بسم الله الرحمن الرحيم

الـ SQL هي أحد الأدوات التي يعتمد عليها محلل البيانات في التعامل مع قواعد البيانات, كذلك المطور لقراءة البيانات من قواعد البيانات أو بناء APIs.

في هذه المقالة سنمر على أهم أوامر SQL ونتطرق لتفصيلها بشكل غير ممل ولا مخل بإذن الله, أولا ماذا تعني هذه الحروف الثلاث

SQL : structured query language

إذا فهي لغة بسيطة تستخدم في التعامل مع قواعد البيانات, لدينا ثلاث أوامر رئيسية فيها

  • CREATE TABLE وتستخدم لإنشاء جدول.
  • DROP TABLE وتستخدم لحذف جدول.
  • SELECT تعرض البيانات التي نود روئيتها والبحث عنها داخل الجدول عن طريق الأوامر التي نكتبها وتسمى هذه الأوامر query, وهي التي سنتحدث عنها في هذه المقالة.

سنقوم بتطبيق الأوامر على الجدول في W3Schools ستجد في الجزء الأيمن من الشاشة الجداول الموجودة والتي سنعمل عليها, بالمناسبة أثناء الكتابة أفترض أنك ستأخذ المفهوم وتقوم بتجربته عدة مرات على أكثر من عمود أو جدول لتقوي فهمك للمفهوم, قد لا أستطرد في تفصيل جميع الحالات لكن أشرح المفهوم بإختصار وبإمكانك التجربة على الجداول الموجودة.

لنبدأ بالأمر الأول

SELECT * FROM Customers

SELECT نستخدمها لاختيار البيانات المراد عرضها
FROM الجدول الذي نريد البيانات منه
فبشكل مبسيط قلنا في الأمر السابق اختر جميع (علامة * تعني جميع أعمدة الجدول)البيانات الموجودة داخل جدول Customers
بعد تنفيذ الأمر ظهرت جميع الأعمدة الي في الجدول, ماذا لو أردت فقط من الجدول CustomerName و Country, اسم العميل ودولته, كيف سأكتب الأمر التالي؟

الأمر سيكون كالتالي

SELECT CustomerName,Country FROM Customers

قمنا باستبدال علامة * التي تعني اختيار جميع الأعمدة بأسماء الأعمدة التي نريدها من جدول Customers

جميل جدا عدد العملاء المعروض أسماؤهم كبير, ماذا لو أردت فقط أول عشر أسماء من الجدول؟ نستخدم هنا LIMIT ونستطيع تحديد عدد الصفوف التي نريدها أن تعرض

SELECT CustomerName,Country FROM Customers LIMIT 5

الان سيتم عرض أول خمسة صفوف في الجدول فقط, وبإمكانك تغيير الرقم لاختيار العدد المناسب

دعنا نمسحLIMIT وننتقل لأمر أخر وهو ORDER BY, وهو أمر نستخدمه لنقوم بترتيب البيانات بناء على عمود من معين إما تصاعديا أو تنازليا

SELECT CustomerName,Country FROM Customers ORDER BY CustomerName

الأمر التالي سيقوم بترتيب الجدول بناء على ترتيب أسماء العملاء حرف A اولا ثم B وهكذا, ماذا لو أردنا أن نعكس الترتيب فنبدأ بأخر حرف إلى الأول فقط نقوم بإضافة DESC بعد اسم العمود وسيقوم بالترتيب تنازلياً

SELECT CustomerName,Country FROM Customers ORDER BY CustomerName DESC

الأمر نفسه ينطبق على الأرقام فلو كان لديك عمود فيه مجموعة أرقام بإمكانك ترتيبها تنازليا وتصاعديا,

لنأخذ مثال أخر على نفس الأمر ORDER BY لكن بوضع قيمتين, أولا سأغير الجدول الذي نعمل عليه من Customers إلى OrderDetails, وهو جدول فيه بيانات الشراء للعملاء بـ Id والكميات و السلع, لكل سلعة Id, يمكنك إلقاء نظرة عليها بإستخدام أمر SELECT الذي تحدثنا عنه سابقاً.

SELECT OrderID,Quantity FROM OrderDetails ORDER BY OrderID, Quantity DESC

بعد أن وضعنا عمودين في ORDER BY سنلاحظ أنه رتب البيانات بناء على العمود الأول الذي هو OrderID ثم قام بترتيب الصف الثاني Quantity بشكل تنازلي, إذا فالترتيب يكون بناء على العمود الأولى ثم العمود الثاني في حال تكررت بيانات العمود الأول.

جميع ما سبق كان يقوم بعمل تحديد على الأعمدة, ماذا إذا أردت تحديد صف معين على سبيل المثال أريد اختيار جميع البضائع المشتراه بـ OrderID برقم 10248, هنا سنحتاج إلى WHERE يكون الحل بسيط جدا كالتالي

SELECT OrderID,Quantity FROM OrderDetails WHERE OrderID = 10248

فأمر WHERE هو عبارة عن شرط لابد أن يتحقق ليعرض الصف, هنا تحققنا من المساواة, بإمكاننا أن نعرض الصفوف التي لديها قيمة الأكبر من 10248

SELECT OrderID,Quantity FROM OrderDetails WHERE OrderID > 10248

وأصغر من >
وأصغر من أو يساوي =>
أكبر من أو يساوي =<
لا يساوي =!

هنا تعرفنا على عمليات المقارنة, وغالبا نستخدمها مع الأعمدة الرقمية, ماذا لو كانت الأعمدة غير رقمية؟ غالبا نستخدم ثلاث معاملات أخرى وهي LIKENOTIN وعملية المساوة طبعا, سنتعرف على ذلك لاحقا في هذه المقالة, أما عملية المساوة فكما في المثال السابق, وتكون القيمة بين علامتي تنصيص “القيمة الغير رقمية”.

جميل جدا, الان سنلقي نظرة على العمليات الحسابية في SQL وسنستخدم جدول Products من الموقع, لنقوم بعرض محتويات الجدول مع التكلفة

SELECT ProductID, ProductName, Price, Price * 3 FROM Products

لاحظ Price * 3 ماذا تعني ببساطة هي عملية ضرب, السعر في 3 على فرض أن هناك عميل طلب 3 قطع فبإمكانك حسابها عن طريق أمر SQL بالأمر السابق, ربما أسم العمود أصبح غريب بعض الشيء, دعنا نعدل الأسم ونجعله total

SELECT ProductID, ProductName, Price, Price * 3 as total FROM Products

ببساطة الان سيعرض أسم العمود بإسم total, هذا العمود فقط سيكون ظاهر في العرض وغير موجود في قاعدة البيانات فعليا, يتم انشاؤه وعرضه أثناء تنفيذ هذا الأمر ويختفي بعده, وبالطبع يمكنك الاستفادة منه, أثناء التعامل مع الجدول, عرفنا من المثال السابق أن هذه العلامة * علامة الضرب, مالعلامات الرياضية الأخرى؟
+ للجمع
– للطرح
/ للقسمة
ولا ننسى as وهو أمر بسيط يطلب تغير أسم عمود لأسم أخر, كما في المثال غيرنا أسم العمود لـ total

أخر نقطة في هذه المقالة هي العلامات المنطقية, تكلمنا عنها سابقا وهي LIKE, IN, NOT, AND,BETWEEN, OR وسنمر على كل واحده منها بإذن الله

نبدأ بـ LIKE تصور معي لو أننا نريد البحث في المنتجات الموجودة في جدول Products ونريد جميع المنتجات التي تقاس بالصندوق, أي أنه في عمود الـ Unit, تحوي كلمة box

SELECT * FROM Products WHERE Unit LIKE “%box%”

الأمر السابق سيقوم بالبحث في الجدول وإيجاد أي كلمة box في عمود Unit ويظهرها, أما علامتي النسبة فهي تستخدم هنا للبحث عن كلمة box وسط الجملة أو وسط الكلمة, فكأننا نقوم في حال وجدت كلمة box في أي مكان داخل الجملة أو الكلمة فهذا ما نبحث عنه, ماذا لو أزلنا هذه العلامة؟ ببساطة يتحول البحث لبحث مساوة عادي كما في علامة =, فعلامة النسبة مفيدة جدا لو كنت تعرف جزء مما تبحث عنه أو أسم من الأسم الكامل لمنتج أو شخص داخل الجدول وهكذا.

ننتقل لـ IN تخيل لو نبحث عن المنتجات التي سعرها 19, 18 من الجدول, فسنقوم بالتالي

SELECT * FROM Products WHERE Price IN (18,19)

تقريبا شبيه بعلامة = لكن لاختيار أكثر من قيمة من الجدول, العمود هنا رقمي لو كان غير رقمي ستضع القيم داخل علامتي تنصيص كما جرت العادة.

قبل تجاوز هذه النقطة لدينا أمرين NOT LIKE و NOT IN, أعتقد أنك أدركت فائدتها من أسمها, وهي تقوم بعكس ما كانت تقوم فيه, تعرض البيانات مستثنية منها ما داخل القوس أو علامة التنصيص.

لنتحدث عن AND, قمنا في مثال سابق بعرض أسعار المنتجات التي قيمتها 19و 18 ماذا لو أردنا عرض المنتجات التي قيمتها بين 18 و 30 ؟ بالتأكيد لن نقوم بكتابة الأرقام رقم رقم. هنا نستخدم AND

SELECT * FROM Products WHERE Price <= 30 AND Price >= 18

قمنا هنا بوضع شرطين يجب تحققهما لنتمكن من عرض القيمة, وعلامة AND تلزمك بتحقق طرفي الشرط ليصبح الشرط صحيح.

مدمنا نبحث عن قيم بين قيمتين هل يمكننا استخدام BETWEEN ؟ بالطبع

SELECT * FROM Products WHERE Price BETWEEN 18 AND 30

من الأوامر الواضحة لكن يجب التنبيه لأمر, يجب مراعاة الترتيب القيمة الأصغر تأتي أولا ثم القيمة الأكبر, فلو قمنا بكتابة

SELECT * FROM Products WHERE Price BETWEEN 30 AND 18

لن تظهر أي نتيجة, كما أن BETWEEN تشمل في البحث القيم المذكورة, أي في مثالنا ستجد أن الحقول التي تحمل 30 و 18 ظاهرة في العرض.

جميل جدا ماذا لو أردنا جميع القيمة التي هي أعلى من 30 و أقل من 18 وهو أمر معاكس للأمر السابق ؟ سنقوم بإستخدام OR بهذا الشكل

SELECT * FROM Products WHERE Price < 18 OR Price > 30

ستجد هنا جميع القيم الأكبر من 30 أو أصغر من 18 ونستطيع أن نقوم بعبارة أخرى, ستجد جميع القيم التي تحقق بها أحد الشرطين.

هنا تنبيه بسيط, SQL ليس case sensitive بمعنى أنه لا يلاحظ هل الحرف كبير أو صغير لكن جرت العادة أن الأوامر الخاصة بـ SQL تكتب بأحرف كبيرة.

جميع التعاملات السابقة كانت داخل جدول واحد, الان سنقوم بالتعامل مع بيانات من أكثر من جدول, سنمر بالتحديد على أمر جديد يسمى join

دعنا نبدأ بالتعرف على جدولي Customers و Orders, جدول Customers فيه بيانات العملاء ومنها CustomerID وهو عبارة عن primary key ونقصد بـ primary key أن هذا العمود فيه قيمة خاصة بكل صف لا تتكرر في صف أخر, مثل الرقم الوطني لكل مواطن, مثل الرقم البنكي لكل بطاقة, فـ primary key يحمل هذه الخاصية يكون كمعرف لكل صف, جميل جدا لدينا أيضا جدول Orders يحوي OrderID كـ primary key, وفيه CustomerID كـ foreign key من جدول Customers

ما نريد تحقيقه هو عرض أسم العميل مع رقم الطلب

SELECT Customers.CustomerName ,Orders.OrderID
FROM Customers
JOIN Orders
WHERE Customers.CustomerID = Orders.CustomerID

هنا بعرض أسم العميل ورقم الطلب و أسم الموظف

SELECT Customers.CustomerName,Orders.OrderID, Employees.LastName, Employees.FirstName
FROM Customers JOIN Orders JOIN Employees
WHERE Customers.CustomerID = Orders.CustomerID AND Orders.EmployeeID = Employees.EmployeeID

alias نقصد فيه الأسم المستعار للجدول مثل

FROM tableName AS t1
JOIN tableName2 AS T2

 

أو نستطيع عدم كتابة AS ونحصل على نفس النتيجة

FROM tableName t1
JOIN tableName2 T2

وتقدر تستخدم الأسم المستعار

SELECT t1.c1, t2.c1
FROM tableName AS t1
JOIN tableName2 AS t2

هنا راح يجيب كل البيانات في الجدول إلي على يسار JOIN, لو في شيء محقق الشرط إلي في ON يحط قيمته لو ما فيه يحط NULL

SELECT Customers.CustomerName ,Orders.OrderID
FROM Customers
LEFT JOIN Orders
ON Customers.CustomerID = Orders.CustomerID

ON تتنفذ قبل عملية JOIN

Aggregate يتم على مستوى العمود وليس على مستوى الصفوف
COUNT: تحسب عدد الصفوف في عمود معين
SUM: تجمع كل القيم في العمود
MIN & MAX: أكبر وأصغر قيمة
AVERAGE: المتوسط الحسابي في العمود

عشان تشيك على الـ Nullity استخدم IS NULL

SELECT CustomerName
FROM Customers
WHERE CustomerID IS NULL

COUNT

SELECT COUNT(*) FROM Customers

يطلع رقم, لو بغيت أخليه في عمود استخدم as

SELECT COUNT(*) AS total FROM Customers

طبعا COUNT ما تحسب الـ NULL لو خليتها على عمود معين, عشان كذا تقدر تحسب فيها الـ NULL في عمود معين

GROUP BY استخدمها لو أبي أنفذ عمليات على جزء من البيانات إلي عندي, مثلا كم مرة طلب كل عميل

SELECT CustomerID,COUNT(*) FROM Orders GROUP BY CustomerID

GROUP BY تستخدم دائما بين WHERE و ORDER BY

DISTINCT is always used in SELECT statements, and it provides the unique rows for all columns written in the SELECT statement

زي هالأمر راح يطلع لك جميع الـ id حقت العملاء بدون تكرار في جدول Orders

SELECT DISTINCT CustomerID FROM Orders

HAVING لو عندك عملية Aggregate بتنفذها على GROUP BY

SELECT CustomerID FROM Orders GROUP BY CustomerID HAVING COUNT(CustomerID) > 2

CASE كنك تتعامل مع IF

LEFT(phone_number, 3)
RIGHT(phone_number, 8)
LENGTH(phone_number)

تساعدك تحدد جزء من النص وتبدأ إما من اليمين أو من اليسار, وتقدر تعرف حجم النص

POSITION تعطيها النص والحرف إلي تدوره وتعطيك رقم الـ index من اليسار

POSITION(‘,’ IN city_state)

STRPOS نفس POSITION بس syntax مختلف

STRPOS(city_state, ‘,’)

LOWER و UPPER يخلون النص أحرف كبيرة أو صغيرة

CONCAT لو تبي تجمع نصين وتحط بينهم شيء يفصل

CONCAT(first_name, ‘ ‘, last_name)

CAST تستخدم لتغيير النوع

CAST(date_column AS DATE)

TRIM تشيل الفراغ بداية ونهاية النص

COALESCE returns the first non-NULL value passed for each row

 

اترك تعليقاً