مقدمة سريعة لأنواع البيانات (Data Types)
لما تتعامل مع التواريخ والأوقات في SQL، لازم تعرف إن فيه أنواع بيانات مخصصة ليها. مش كل قاعدة بيانات زي التانية بالظبط، بس دي أشهر الأنواع اللي هتلاقيها:
DATE: لتخزين التاريخ فقط (سنة، شهر، يوم).TIME: لتخزين الوقت فقط (ساعة، دقيقة، ثانية، أجزاء الثانية).DATETIME/TIMESTAMP: لتخزين التاريخ والوقت مع بعض.TIMESTAMPغالباً بيكون أدق شوية وممكن يتسجل فيه معلومات المنطقة الزمنية (Time Zone). في SQL Server، ممكن تلاقيDATETIME2اللي بيدي دقة أعلى منDATETIMEالعادي.
الحصول على التاريخ والوقت الحاليين
دي من أبسط الحاجات اللي هتحتاجها. عايز تعرف إيه الوقت دلوقتي؟ عندك كذا دالة حسب نوع قاعدة البيانات:
ملاحظة: الدالة
GETDATE()مش موجودة في كل قواعد البيانات، لكنCURRENT_TIMESTAMPأوNOW()هتشتغل معاك في أغلب الأحيان.
في SQL Server:
SELECT GETDATE();
SELECT SYSDATETIME(); -- أدق شوية
في MySQL و PostgreSQL:
SELECT NOW();
SELECT CURRENT_TIMESTAMP;
استخراج أجزاء من التاريخ والوقت
أحياناً بتحتاج تستخرج السنة بس، أو الشهر، أو اليوم، أو الساعة. فيه دوال مخصصة لكده:
في SQL Server:
SELECT YEAR(GETDATE()) AS CurrentYear,
MONTH(GETDATE()) AS CurrentMonth,
DAY(GETDATE()) AS CurrentDay,
DATEPART(HOUR, GETDATE()) AS CurrentHour;
في MySQL:
SELECT YEAR(NOW()) AS CurrentYear,
MONTH(NOW()) AS CurrentMonth,
DAY(NOW()) AS CurrentDay,
HOUR(NOW()) AS CurrentHour;
في PostgreSQL (وهي طريقة قياسية أكتر):
SELECT EXTRACT(YEAR FROM NOW()) AS CurrentYear,
EXTRACT(MONTH FROM NOW()) AS CurrentMonth,
EXTRACT(DAY FROM NOW()) AS CurrentDay,
EXTRACT(HOUR FROM NOW()) AS CurrentHour;
إضافة وطرح الفترات الزمنية
عايز تضيف 5 أيام لتاريخ معين؟ أو تطرح شهرين؟ دي دوال هتفيدك:
في SQL Server (دالة DATEADD):
SELECT DATEADD(day, 5, GETDATE()) AS FiveDaysLater,
DATEADD(month, -2, GETDATE()) AS TwoMonthsAgo;
في MySQL و PostgreSQL (باستخدام INTERVAL):
SELECT NOW() + INTERVAL 5 DAY AS FiveDaysLater,
NOW() - INTERVAL 2 MONTH AS TwoMonthsAgo;
تنسيق التواريخ والأوقات للعرض
لما بتجيب التاريخ من قاعدة البيانات، ممكن يكون تنسيقه مش مناسب للعرض للمستخدم. ممكن تحتاج تظهره بصيغة "يوم/شهر/سنة" أو "اسم الشهر، اليوم، السنة".
في SQL Server (باستخدام FORMAT أو CONVERT):
SELECT FORMAT(GETDATE(), 'dd/MM/yyyy') AS FormattedDate,
FORMAT(GETDATE(), 'hh:mm tt') AS FormattedTime,
CONVERT(VARCHAR, GETDATE(), 103) AS OldStyleFormat; -- 103 for dd/mm/yyyy
في MySQL (باستخدام DATE_FORMAT):
SELECT DATE_FORMAT(NOW(), '%d/%m/%Y') AS FormattedDate,
DATE_FORMAT(NOW(), '%h:%i %p') AS FormattedTime;
في PostgreSQL (باستخدام TO_CHAR):
SELECT TO_CHAR(NOW(), 'DD/MM/YYYY') AS FormattedDate,
TO_CHAR(NOW(), 'HH12:MI AM') AS FormattedTime;
التحويل من نص إلى تاريخ/وقت
أحياناً بيجيلك التاريخ كـ String (نص) وعايز تحوله لنوع بيانات تاريخ عشان تقدر تعمل عليه عمليات. هنا بتيجي دوال التحويل:
في SQL Server (باستخدام CONVERT أو CAST):
SELECT CONVERT(DATE, '2023-10-26') AS ConvertedDate,
CAST('2023-10-26 14:30:00' AS DATETIME) AS ConvertedDateTime;
في MySQL (باستخدام STR_TO_DATE):
SELECT STR_TO_DATE('26/10/2023', '%d/%m/%Y') AS ConvertedDate;
في PostgreSQL (باستخدام TO_DATE أو TO_TIMESTAMP):
SELECT TO_DATE('26-Oct-2023', 'DD-Mon-YYYY') AS ConvertedDate;
SELECT TO_TIMESTAMP('2023-10-26 14:30:00', 'YYYY-MM-DD HH24:MI:SS') AS ConvertedTimestamp;
حساب الفرق بين تاريخين
عايز تعرف كام يوم بين تاريخين؟ أو كام شهر؟ فيه دوال مخصصة لكده:
في SQL Server (دالة DATEDIFF):
SELECT DATEDIFF(day, '2023-10-01', GETDATE()) AS DaysDifference,
DATEDIFF(month, '2023-01-01', GETDATE()) AS MonthsDifference;
في MySQL (دالة DATEDIFF لحساب الأيام، أو TIMESTAMPDIFF لأي وحدة):
SELECT DATEDIFF(NOW(), '2023-10-01') AS DaysDifference;
SELECT TIMESTAMPDIFF(MONTH, '2023-01-01', NOW()) AS MonthsDifference;
في PostgreSQL (ممكن تطرح التواريخ مباشرة أو تستخدم AGE):
SELECT NOW()::DATE - '2023-10-01'::DATE AS DaysDifference;
SELECT AGE(NOW(), '2023-01-01') AS TimeDifference; -- هترجع لك الفرق على هيئة "سنة شهر يوم"
نصيحة أخيرة
تذكر دايماً: أفضل ممارسة هي إنك تخزن التواريخ والأوقات في قاعدة البيانات بنوع البيانات المخصص ليها (
DATE,DATETIME,TIMESTAMP) وتخلي التنسيق للعرض على مستوى التطبيق (أو تستخدم دوال الـ SQL للتنسيق لو محتاج). ده بيضمن دقة البيانات وبيخلي العمليات عليها أسهل وأسرع.