0Pricing
SQL Interview Prep · درس

الحساب باستخدام التواريخ والفواصل الزمنية

إضافة الفترات وطرحها وحساب الفروق بين التواريخ

الحساب باستخدام التواريخ والفواصل الزمنية درس مجاني في SQL Interview Prep على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في SQL Interview Prep، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة SQL Interview Prep 4 دروس في المجموع.

لماذا تظهر حسابات التواريخ في المقابلات

تُعد العمليات الحسابية على التواريخ من أكثر مهارات SQL عملية، لذلك يعتمد عليها المحاوِرون كثيرًا في أدوار محللي البيانات والواجهة الخلفية. فكل سؤال تجاري تقريبًا يتضمن عنصرًا زمنيًا: آخر 30 يومًا، والطلبات لكل أسبوع، وعدد الأيام منذ التسجيل.

لكن المأزق هو أن دوال التاريخ هي الأقل توحيدًا في SQL. فالعملية نفسها لها صيغ مختلفة في PostgreSQL وMySQL وSQL Server. يوضح المرشح القوي الفكرة بوضوح أولًا، ثم يكيّف الصيغة مع اللهجة المستخدمة.

  • إضافة فترة زمنية أو طرحها
  • حساب الفرق بين تاريخين
  • التعامل مع قيم INTERVAL

نوع INTERVAL

في PostgreSQL ومعيار SQL، تُعد الفترة الزمنية قيمة من الدرجة الأولى تُسمى interval. ويمكنك إضافتها إلى تاريخ أو طابع زمني باستخدام معاملي + و- العاديين.

هذه هي الطريقة الأوضح للتعبير عن «قبل 30 يومًا» أو «بعد 3 أشهر من الآن»، ويحبها المحاوِرون لأنها تُقرأ كما لو كانت لغة طبيعية.

SELECT
  CURRENT_DATE,
  CURRENT_DATE + INTERVAL '7 days'   AS next_week,
  CURRENT_DATE - INTERVAL '1 month'  AS last_month,
  NOW() + INTERVAL '90 minutes'      AS soon;

إضافة الفترات الزمنية بين اللهجات

غالبًا ما يسأل المحاوِرون: «كيف ستضيف 7 أيام في MySQL مقارنةً بـSQL Server؟» إن معرفة اللهجات الثلاث الكبرى تدل على خبرة عملية حقيقية.

  • PostgreSQL: d + INTERVAL '7 days'
  • MySQL: DATE_ADD(d, INTERVAL 7 DAY)
  • SQL Server: DATEADD(day, 7, d)

المفهوم متطابق؛ ولا يتغير إلا الأسلوب الكتابي. اذكر دائمًا اللهجة التي تكتب لها.

-- MySQL
SELECT DATE_ADD(order_date, INTERVAL 7 DAY) AS due_date FROM orders;

-- SQL Server
SELECT DATEADD(day, 7, order_date) AS due_date FROM orders;

الفرق بين تاريخين

الجانب الآخر من العمليات الحسابية على التواريخ هو حساب المدة الفاصلة بين تاريخين. وتعتمد النتيجة على الوحدة واللهجة المستخدمة.

في PostgreSQL، يؤدي طرح قيمتي date إلى إعطاء عدد صحيح يمثل الأيام مباشرةً. أما طرح قيمتي timestamp فيعطي فترة زمنية.

-- Postgres: date - date returns an integer (days)
SELECT shipped_date - order_date AS days_to_ship
FROM orders;

DATEDIFF ومشكلاته

توجد DATEDIFF في MySQL وSQL Server، لكنها تتصرف بشكل مختلف، وهذه من النقاط الخادعة المفضلة في المقابلات.

  • MySQL: تعيد DATEDIFF(end, start) عدد الأيام الكاملة فقط.
  • SQL Server: تستقبل DATEDIFF(unit, start, end) وحدةً زمنية، وتحسب عمليات عبور الحدود لا الوحدات الكاملة المنقضية.

ويهم هذا السلوك عند الحدود: تعيد DATEDIFF(year, '2023-12-31', '2024-01-01') في SQL Server القيمة 1، رغم مرور يوم واحد فقط.

-- SQL Server: counts boundaries, not elapsed time
SELECT DATEDIFF(year, '2023-12-31', '2024-01-01'); -- 1
SELECT DATEDIFF(day,  '2023-12-31', '2024-01-01'); -- 1

حساب العمر بالسنوات بطريقة صحيحة

«احسب عمر العميل بالسنوات» سؤال تقليدي. فالطريقة الساذجة، التي تقسم فرق الأيام على 365، تنحرف بسبب السنوات الكبيسة. يوفر PostgreSQL الدالة AGE() التي تعيد فترة زمنية تقويمية حقيقية.

ولحساب عدد صحيح واضح للسنوات، استخرج جزء السنة من العمر.

-- Postgres
SELECT
  birth_date,
  AGE(CURRENT_DATE, birth_date)               AS exact_age,
  EXTRACT(YEAR FROM AGE(CURRENT_DATE, birth_date)) AS age_years
FROM customers;

مثال تطبيقي: الطلبات خلال آخر 30 يومًا

هذا مرشح شائع جدًا في أسئلة المقابلات. والطريقة الصحيحة هي مقارنة عمود التاريخ بحدّ فاصل محسوب، لا وضع العمود داخل دالة.

تُبقي مقارنة order_date بحدّ فاصل ثابت أي فهرس على order_date قابلًا للاستخدام. وسنعود إلى هذه النقطة المتعلقة بالفهرس لاحقًا.

SELECT COUNT(*) AS recent_orders
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '30 days';

النطاقات نصف المفتوحة لشهر تقويمي

عندما يُطلب منك «جميع الطلبات في مارس 2024»، تجنب استخدام BETWEEN '2024-03-01' AND '2024-03-31' على عمود طابع زمني. فهذا يفوّت الصفوف عند الساعة 11 مساءً في 31 مارس، كما أنه عرضة لأخطاء حدودية بمقدار واحد.

النمط المتين هو فاصل نصف مفتوح: أكبر من أو يساوي بداية الشهر، وأصغر من بداية الشهر التالي. ويعمل ذلك مع أي دقة للعمود.

SELECT *
FROM orders
WHERE order_ts >= DATE '2024-03-01'
  AND order_ts <  DATE '2024-04-01';

EXTRACT وأجزاء التاريخ

يُعد استخراج مكوّن واحد من تاريخ أمرًا متكررًا في أعمال إعداد التقارير. والدالة القياسية هي EXTRACT(part FROM d)، وتدعمها PostgreSQL وMySQL.

  • EXTRACT(YEAR FROM d)، وMONTH، وDAY
  • EXTRACT(DOW FROM d) ليوم الأسبوع
  • يستخدم SQL Server بدلًا منها DATEPART(weekday, d)

ملاحظة: يؤدي استخراج MONTH وحده إلى تجميع أشهر مارس من سنوات مختلفة معًا، وهو ما نادرًا ما تريده.

SELECT
  EXTRACT(YEAR  FROM order_ts) AS yr,
  EXTRACT(MONTH FROM order_ts) AS mo,
  COUNT(*) AS n
FROM orders
GROUP BY 1, 2
ORDER BY 1, 2;

مثال أعمق: الأيام المتبقية حتى عيد الميلاد التالي

هذه مسألة حسابية أصعب تجمع بين الاستخراج والإضافة. أنشئ عيد ميلاد هذا العام من شهر الميلاد ويومه، وإذا كان قد مرّ بالفعل، فانتقل إلى العام التالي.

إن شرح هذه الخطوات بصوت مسموع يوضح للمحاوِر أنك قادر على التفكير في الحالات الحدّية، مثل عيد ميلاد وقع بالفعل هذا العام.

-- Postgres
SELECT
  name,
  CASE
    WHEN MAKE_DATE(EXTRACT(YEAR FROM CURRENT_DATE)::int,
                   EXTRACT(MONTH FROM birth_date)::int,
                   EXTRACT(DAY FROM birth_date)::int) >= CURRENT_DATE
    THEN MAKE_DATE(EXTRACT(YEAR FROM CURRENT_DATE)::int,
                   EXTRACT(MONTH FROM birth_date)::int,
                   EXTRACT(DAY FROM birth_date)::int) - CURRENT_DATE
    ELSE MAKE_DATE(EXTRACT(YEAR FROM CURRENT_DATE)::int + 1,
                   EXTRACT(MONTH FROM birth_date)::int,
                   EXTRACT(DAY FROM birth_date)::int) - CURRENT_DATE
  END AS days_until
FROM customers;

اليوم الأول والأخير من الشهر

«أعطني اليوم الأخير من شهر كل طلب» سؤال يختبر ما إذا كنت ستستخدم دالة مدمجة أم ستعيد اختراعها. يركّب PostgreSQL الدالة DATE_TRUNC مع العمليات الحسابية على الفترات الزمنية، بينما يوفر MySQL الدالة LAST_DAY() مباشرةً.

الحيلة لحساب اليوم الأخير في Postgres هي: التقريب إلى بداية الشهر، وإضافة شهر واحد، ثم طرح يوم واحد.

-- Postgres
SELECT
  DATE_TRUNC('month', order_ts)                              AS month_start,
  DATE_TRUNC('month', order_ts) + INTERVAL '1 month - 1 day' AS month_end
FROM orders;

-- MySQL: LAST_DAY(order_ts)

تحقق سريع

اختبر فهمك لسلوك حساب الفروق بين التواريخ عبر اللهجات المختلفة.

مراجعة: العمليات الحسابية على التواريخ والفترات الزمنية

أهم النقاط التي ينبغي تذكرها للمقابلة:

  • استخدم قيم INTERVAL مع +/- في Postgres؛ وDATE_ADD/DATEDIFF في MySQL؛ وDATEADD/DATEDIFF في SQL Server.
  • تحسب DATEDIFF في SQL Server عمليات عبور الحدود لا الوحدات المنقضية، وهذه أهم نقطة خادعة.
  • لحساب العمر بالسنوات، استخرج القيمة من AGE() بدلًا من قسمة الأيام على 365.
  • صفِّ الصفوف الحديثة بمقارنة العمود بحدّ فاصل محسوب، واستخدم نطاقات نصف مفتوحة (>= start AND < next) للنوافذ الشهرية.

اذكر المفهوم أولًا، ثم كيّف الصيغة مع اللهجة المستخدمة.

الأسئلة الشائعة

هل درس «الحساب باستخدام التواريخ والفواصل الزمنية» مجاني؟

نعم — نص درس «الحساب باستخدام التواريخ والفواصل الزمنية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة SQL Interview Prep، انتقل إلى CoddyKit PRO. تتضمن دورة SQL Interview Prep 4 دروس في المجموع.

ماذا ستتعلم في «الحساب باستخدام التواريخ والفواصل الزمنية»؟

إضافة الفترات وطرحها وحساب الفروق بين التواريخ تتمرن على SQL Interview Prep مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ SQL Interview Prep؟

لا تُشترط خبرة سابقة. SQL Interview Prep على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «الحساب باستخدام التواريخ والفواصل الزمنية»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس SQL Interview Prep هذا؟

نعم. كل درس في SQL Interview Prep يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. الحساب باستخدام التواريخ والفواصل الزمنية
  2. اقتطاع التواريخ وتجميعها في فئات
  3. تحليل السلاسل النصية وتنسيقها
  4. المناطق الزمنية والطوابع الزمنية
← العودة إلى SQL Interview Prep