PostgreSQL: أساسيات استعلام SELECT في PostgreSQL
آخر تحديث: 2026-08-26
1. ما ستتعلمه
- استخدام
SELECTلاستعلام الأعمدة والتعبيرات والأسماء المستعارة - إزالة الصفوف المكررة بـ
DISTINCT - تصفية البيانات بـ
WHERE - الترتيب بـ
ORDER BY(بما في ذلك ميزة PostgreSQL الفريدةNULLS FIRST/LAST) - تقسيم الصفحات بـ
LIMIT/OFFSETوFETCH FIRST
2. القصة
Bob هو مهندس قواعد بيانات في منصة تجارة إلكترونية. المنصة تولد حوالي 10,000 طلب يومياً، متراكمة 100,000 سجل خلال آخر 30 يوماً. فريق العمليات يطلب منه:
- استعلام جميع طلبات آخر 30 يوماً، مرتبة حسب المبلغ من الأعلى إلى الأقل
- عرض 50 لكل صفحة، مع دعم التقسيم
- تصفية الطلبات الملغاة
- إزالة معرفات العملاء المكررة من العرض
يحتاج Bob إلى SELECT، WHERE، ORDER BY، LIMIT/OFFSET، و DISTINCT لإنجاز المهمة.
3. المفهوم: أساسيات SELECT
(1) نظرة عامة على صيغة SELECT
SELECT column1, column2, ...
FROM table_name
[WHERE condition]
[ORDER BY column [ASC|DESC] [NULLS FIRST|NULLS LAST]]
[LIMIT count [OFFSET start]];
SELECT هي عبا��ة SQL الأكثر استخداماً، تُستخدم لاسترجاع البيانات من جدول واحد أو أكثر.
(2) جميع الأعمدة مقابل أعمدة محددة
| النمط | الوصف | الأداء | موصى به لـ |
|---|---|---|---|
SELECT * |
يعيد جميع الأعمدة | أسوأ — ينقل بيانات زائدة | استكشاف بنية الجدول بسرعة |
SELECT col1, col2 |
يعيد الأعمدة المحددة فقط | أفضل — I/O أقل | استعلامات الإنتاج |
(1) ▶ مثال
SELECT * FROM orders;
Output:
id | name | value
----+----------+-------
1 | example | 42
(1 row)
(2) ▶ مثال
SELECT order_id, customer_id, total_amount, order_date
FROM orders;
Output:
id | name | value
----+----------+-------
1 | example | 42
(1 row)
(3) الأسماء المستعارة للأعمدة
استخدم الكلمة المفتاحية AS (اختيارية) لإعطاء العمود أو التعبير اسماً مستعاراً لجعل النتائج أكثر قابلية للقراءة.
| الاستخدام | مثال | الوصف |
|---|---|---|
AS صريح |
price * qty AS subtotal |
موصى به — واضح |
حذف AS |
price * qty subtotal |
صالح لكن أقل وض��حاً |
| اسم مستعار مقتبس | total_amount AS "Order Total" |
مطلوب عندما يحتوي الاسم على مسافات أو أحرف كبيرة/صغيرة |
(3) ▶ مثال
SELECT
order_id,
total_amount AS amount,
order_date AS "Order Date",
total_amount * 0.08 AS tax
FROM orders;
Output:
id | name | value
----+----------+-------
1 | example | 42
(1 row)
(4) التعبيرات والأعمدة المحسوبة
SELECT يمكنه أكثر من قراءة الأعمدة — يمكنه أيضاً كتابة تعبيرات حسابية، استدعاءات دوال، إلخ، لإنتاج أعمدة محسوبة.
(4) ▶ مثال
SELECT
product_name,
unit_price,
unit_price * 1.1 AS price_with_tax,
ROUND(unit_price * 1.1, 2) AS rounded_price
FROM products;
Output:
id | name | value
----+----------+-------
1 | example | 42
(1 row)
4. المفهوم: إزالة التكرار بـ DISTINCT
(1) إزالة التكرار الأساسية
DISTINCT تزيل الصفوف المكررة من مجموعة النتائج، تُستخدم عادةً لعد القيم الفريدة.
(5) ▶ مثال
SELECT DISTINCT customer_id
FROM orders;
Output:
id | name | value
----+----------+-------
1 | example | 42
(1 row)
(2) إزالة التكرار متعددة الأعمدة
DISTINCT تنطبق على تركيبة جميع الأعمدة المحددة، وليس عموداً واحداً.
| العبارة | نطاق إزالة التكرار |
|---|---|
SELECT DISTINCT a |
إزالة التكرار حسب a |
SELECT DISTINCT a, b |
إزالة التكرار حسب تركيبة (a, b) |
SELECT DISTINCT ON (a) a, b |
PostgreSQL فقط: إزالة التكرار حسب a، الاحتفاظ بأول صف لكل مجموعة |
(6) ▶ مثال
SELECT DISTINCT customer_id, order_status
FROM orders;
Output:
id | name | value
----+----------+-------
1 | example | 42
(1 row)
(3) DISTINCT ON: صيغة PostgreSQL فقط
DISTINCT ON (expr) تزيل التكرار حسب تعبير معين وتعيد الصف الأول في كل مجموعة (تقترن مع ORDER BY لتحديد أي صف).
(7) ▶ مثال
SELECT DISTINCT ON (customer_id)
customer_id, order_id, order_date, total_amount
FROM orders
ORDER BY customer_id, order_date DESC;
Output:
id | name | value
----+----------+-------
1 | example | 42
(1 row)
5. المفهوم: تصفية WHERE
(1) معاملات المقارنة الأساسية
| المعامل | المعنى | مثال |
|---|---|---|
= |
يساوي | order_status = 'completed' |
<> أو != |
لا يساوي | total_amount <> 0 |
> |
أكبر من | total_amount > 100 |
< |
أصغر من | total_amount < 50 |
>= |
أكبر من أو يساوي | total_amount >= 100 |
<= |
أصغر من أو يساوي | total_amount <= 500 |
(8) ▶ مثال
SELECT order_id, customer_id, total_amount
FROM orders
WHERE order_status = 'completed';
Output:
id | name | value
----+----------+-------
1 | example | 42
(1 row)
(2) تصفية التاريخ
مقارنة التاريخ هي إحدى أكثر احتياجات التصفية شيوعاً في التجارة الإلكترونية.
(9) ▶ مثال
SELECT order_id, customer_id, total_amount, order_date
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '30 days';
Output:
id | name | value
----+----------+-------
1 | example | 42
(1 row)
(3) دمج شروط متعددة
استخدم AND، OR، NOT لدمج الشروط. الأولوية: NOT > AND > OR؛ استخدم الأقواس للتحكم الصريح.
(10) ▶ مثال
SELECT order_id, total_amount, order_status
FROM orders
WHERE order_status = 'completed'
AND total_amount > 500
AND order_date >= '2025-01-01';
Output:
id | name | value
----+----------+-------
1 | example | 42
(1 row)
6. المفهوم: ترتيب ORDER BY
(1) الترتيب الأساسي
ORDER BY افتراضياً تصاعدي (ASC)؛ يمكنك تحديد تنازلي (DESC). يدعم الترتيب حسب اسم العمود، الاسم المستعار، أو موضع العمود.
| نمط الترتيب | الصيغة | الوصف |
|---|---|---|
| تصاعدي | ORDER BY col ASC |
افتراضي، ASC اختياري |
| تنازلي | ORDER BY col DESC |
من الأعلى إلى الأقل |
| بالاسم المستعار | ORDER BY amount DESC |
استخدم الاسم المستعار من SELECT |
| بالموضع | ORDER BY 3 DESC |
حس�� العمود الثالث في قائمة SELECT (غير موصى به) |
(11) ▶ مثال
SELECT order_id, customer_id, total_amount
FROM orders
ORDER BY total_amount DESC;
Output:
id | name | value
----+----------+-------
1 | example | 42
(1 row)
(2) ترتيب متعدد الأعمدة
مع الترتيب متعدد الأعمدة، تُرتب الصفوف حسب العمود الأول؛ تُكسر التعادلات بالعمود الثاني، وهكذا.
(12) ▶ مثال
SELECT order_id, order_status, total_amount
FROM orders
ORDER BY order_status ASC, total_amount DESC;
Output:
id | name | value
----+----------+-------
1 | example | 42
(1 row)
(3) NULLS FIRST / NULLS LAST: ميزة PostgreSQL
PostgreSQL تعامل NULL كأكبر قيمة افتراضياً (الأخيرة في الترتيب التصاعدي، الأولى في التنازلي). يمكنك التحكم الصريح في موضع NULL بـ NULLS FIRST و NULLS LAST.
| الترتيب | الموضع الافتراضي لـ NULL | قابل للتعديل إلى |
|---|---|---|
ASC |
NULL في النهاية | NULLS FIRST ينقل NULL للبداية |
DESC |
NULL في البداية | NULLS LAST ينقل NULL للنهاية |
(13) ▶ مثال
SELECT product_name, discount_rate
FROM products
ORDER BY discount_rate DESC NULLS LAST;
Output:
count
-------
5
(1 row)
7. المفهوم: تقسيم الصفحات بـ LIMIT و FETCH FIRST
(1) LIMIT / OFFSET
LIMIT يحدد عدد الصفوف المعادة؛ OFFSET يتخطى عدداً معيناً من الصفوف. معاً ينفذان تقسيم الصفحات.
(14) ▶ مثال
SELECT order_id, customer_id, total_amount, order_date
FROM orders
WHERE order_status = 'completed'
ORDER BY total_amount DESC
LIMIT 50 OFFSET 100;
Output:
id | name | value
----+----------+-------
1 | example | 42
(1 row)
(2) FETCH FIRST: صيغة SQL القياسية
PostgreSQL تدعم أيضاً صيغة FETCH FIRST القياسية في SQL، متطابقة دلالياً مع LIMIT.
| الصيغة | المكافئ | الوصف |
|---|---|---|
LIMIT 10 |
FETCH FIRST 10 ROWS ONLY |
الشكل القياسي |
LIMIT 10 OFFSET 20 |
OFFSET 20 ROWS FETCH FIRST 10 ROWS ONLY |
شكل التقسيم القياسي |
(15) ▶ مثال
SELECT order_id, customer_id, total_amount
FROM orders
ORDER BY total_amount DESC
OFFSET 100 ROWS
FETCH FIRST 50 ROWS ONLY;
Output:
id | name | value
----+----------+-------
1 | example | 42
(1 row)
(3) معادلة تقسيم الصفحات
| المعامل | الحساب |
|---|---|
الصفحة page |
تبدأ من 1 |
حجم الصفحة size |
مثلاً 50 |
OFFSET |
(page - 1) * size |
LIMIT |
size |
(16) ▶ مثال
page=3
size=50
offset=$(( (page - 1) * size ))
psql -c "SELECT order_id, total_amount FROM orders ORDER BY total_amount DESC LIMIT $size OFFSET $offset;"
Output:
# psql command executed successfully
8. مخطط التدفق: ترتيب تنفيذ استعلام SELECT
flowchart TD
A[FROM orders] --> B[تصفية WHERE]
B --> C[SELECT الأعمدة / التعبيرات]
C --> D[DISTINCT]
D --> E[ترتيب ORDER BY]
E --> F[تقسيم LIMIT / OFFSET]
F --> G[مجموعة النتائج]
style A fill:#e1f5fe
style B fill:#fff3e0
style C fill:#e8f5e9
style D fill:#f3e5f5
style E fill:#fce4ec
style F fill:#e0f2f1
style G fill:#c8e6c9
9. مثال شامل
أكمل Bob متطلبات فريق العمليات: استعلام الطلبات المكتملة من آخر 30 يوماً، مقسمة تنازلياً حسب المبلغ، مع الإبلاغ عن عدد العملاء المميزين.
-- الخطوة 1: طلبات آخر 30 يوماً المكتملة، مقسمة تنازلياً حسب المبلغ
SELECT
order_id,
customer_id,
total_amount,
total_amount * 0.08 AS tax_amount,
order_date AS "Order Date",
order_status
FROM orders
WHERE order_status = 'completed'
AND order_date >= CURRENT_DATE - INTERVAL '30 days'
ORDER BY total_amount DESC NULLS LAST
LIMIT 50 OFFSET 0;
-- الخطوة 2: عد العملاء المميزين في تلك الطلبات
SELECT COUNT(DISTINCT customer_id) AS unique_customers
FROM orders
WHERE order_status = 'completed'
AND order_date >= CURRENT_DATE - INTERVAL '30 days';
-- الخطوة 3: آخر طلب لكل عميل (DISTINCT ON)
SELECT DISTINCT ON (customer_id)
customer_id,
order_id,
total_amount,
order_date
FROM orders
WHERE order_status = 'completed'
AND order_date >= CURRENT_DATE - INTERVAL '30 days'
ORDER BY customer_id, total_amount DESC;
-- الخطوة 4: أفضل 10 طلبات مع الإجمالي المحسوب (السعر + الضريبة)
SELECT
order_id,
customer_id,
total_amount,
ROUND(total_amount * 1.08, 2) AS total_with_tax,
order_date
FROM orders
WHERE order_status = 'completed'
AND order_date >= CURRENT_DATE - INTERVAL '30 days'
ORDER BY total_with_tax DESC
FETCH FIRST 10 ROWS ONLY;
❓ أسئلة شائعة
📖 ملخص
SELECTهو أساس استعلامات SQL، يدعم أسماء الأعمدة والتعبيرات والأسماء المستعارةDISTINCTتزيل الصفوف المكررة؛DISTINCT ONهي صيغة خاصة بـ PostgreSQLWHEREتصفي الصفوف بمعاملات المقارنة وتدعم تركيباتAND/OR/NOTORDER BYتدعمASC/DESCوميزة PostgreSQL الفريدةNULLS FIRST/LASTLIMIT/OFFSETوFETCH FIRSTينفذان تقسيم الصفحات؛ الإزاحات الكبيرة تستدعي تقسيم keyset- ترتيب التنفيذ المنطقي لـ SQL: FROM → WHERE → SELECT → DISTINCT → ORDER BY → LIMIT
📝 تمارين
-
⭐ اكتب استعلاماً يختار
product_nameوunit_priceمنproducts، مرتباً تصاعدياً حسب السعر، معيداً أول 10 صفوف فقط. -
⭐⭐ اكتب استعلاماً يختار طلبات آخر 7 أيام من
orders، مصفياً لـtotal_amount > 200، مرتباً حسبorder_date DESC، مستخدماًFETCH FIRST 20 ROWS ONLY. -
⭐⭐⭐ استخدم
DISTINCT ONلاستعلام طلب كلcustomer_idصاحب أعلى مبلغ (تلميح:ORDER BY customer_id, total_amount DESC)، وعد كم من هؤلاء العملاء لديهم أقصى طلب فردي يتجاوز 1,000 دولار.