توابع تاریخ و زمان، جدولهای موقت، کپی جدول و زیرپرسوجو در SQL
توابع تاریخ و زمان SQL
این بخش فهرست توابع مهم مرتبط با تاریخ و زمان را ارائه میکند. RDBMSهای مختلف ممکن است توابع دیگری نیز داشته باشند؛ فهرست و مثالهای این بخش بر پایهٔ MySQL در متن منبع هستند.
| تابع | کاربرد |
ADDDATE() | افزودن مقدار به تاریخ. |
ADDTIME() | افزودن زمان. |
CONVERT_TZ() | تبدیل مقدار تاریخوزمان از یک منطقهٔ زمانی به منطقهٔ زمانی دیگر. |
CURDATE() | برگرداندن تاریخ جاری. |
CURRENT_DATE(), CURRENT_DATE | نامهای مترادف CURDATE(). |
CURRENT_TIME(), CURRENT_TIME | نامهای مترادف CURTIME(). |
CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP | نامهای مترادف NOW(). |
CURTIME() | برگرداندن زمان جاری. |
DATE_ADD() | افزودن یک بازهٔ زمانی به تاریخ. |
DATE_FORMAT() | قالببندی تاریخ بر اساس قالب مشخص. |
DATE_SUB() | کمکردن یک بازهٔ زمانی از تاریخ. |
DATE() | استخراج بخش تاریخ از عبارت تاریخ یا تاریخوزمان. |
DATEDIFF() | محاسبهٔ اختلاف دو تاریخ بر حسب روز. |
DAY() | مترادف DAYOFMONTH(). |
DAYNAME() | برگرداندن نام روز هفته. |
DAYOFMONTH() | شمارهٔ روز ماه، از ۱ تا ۳۱. |
DAYOFWEEK() | شاخص روز هفته. |
DAYOFYEAR() | شمارهٔ روز سال، از ۱ تا ۳۶۶. |
EXTRACT | استخراج بخشی از تاریخ. |
FROM_DAYS() | تبدیل شمارهٔ روز به تاریخ. |
FROM_UNIXTIME() | تبدیل برچسب زمانی Unix به نمایش تاریخوزمان. |
HOUR() | استخراج ساعت. |
LAST_DAY() | برگرداندن آخرین روز ماه متناظر با آرگومان. |
LOCALTIME(), LOCALTIME | مترادف NOW(). |
LOCALTIMESTAMP(), LOCALTIMESTAMP | مترادف NOW(). |
MAKEDATE() | ساخت تاریخ از سال و شمارهٔ روز سال. |
MAKETIME() | ساخت زمان از ساعت، دقیقه و ثانیه. |
MICROSECOND() | استخراج میکروثانیه. |
MINUTE() | استخراج دقیقه. |
MONTH() | استخراج شمارهٔ ماه. |
MONTHNAME() | برگرداندن نام ماه. |
NOW() | برگرداندن تاریخ و زمان جاری. |
PERIOD_ADD() | افزودن ماه به دورهٔ سالـماه. |
PERIOD_DIFF() | برگرداندن تعداد ماه میان دو دوره. |
QUARTER() | برگرداندن فصل سال از ۱ تا ۴. |
SEC_TO_TIME() | تبدیل ثانیه به قالب زمان. |
SECOND() | استخراج ثانیه، از ۰ تا ۵۹. |
STR_TO_DATE() | تبدیل رشته به تاریخ/زمان بر اساس قالب. |
SUBDATE() | در شکل INTERVAL مترادف DATE_SUB(). |
SUBTIME() | کمکردن زمان. |
SYSDATE() | برگرداندن زمان اجرای تابع. |
TIME_FORMAT() | قالببندی مقدار زمان. |
TIME_TO_SEC() | تبدیل زمان به ثانیه. |
TIME() | استخراج بخش زمان از عبارت. |
TIMEDIFF() | محاسبهٔ اختلاف دو زمان یا دو تاریخوزمان همنوع. |
TIMESTAMP() | با یک آرگومان، تبدیل عبارت به تاریخوزمان؛ با دو آرگومان، جمع تاریخوزمان و زمان. |
TIMESTAMPADD() | افزودن بازه به عبارت تاریخوزمان. |
TIMESTAMPDIFF() | محاسبهٔ اختلاف دو عبارت تاریخوزمان در واحد مشخص. |
TO_DAYS() | تبدیل تاریخ به شمارهٔ روز. |
UNIX_TIMESTAMP() | برگرداندن برچسب زمانی Unix. |
UTC_DATE() | تاریخ جاری UTC. |
UTC_TIME() | زمان جاری UTC. |
UTC_TIMESTAMP() | تاریخ و زمان جاری UTC. |
WEEK() | شمارهٔ هفته. |
WEEKDAY() | شاخص روز هفته. |
WEEKOFYEAR() | هفتهٔ تقویمی سال، از ۱ تا ۵۳. |
YEAR() | استخراج سال. |
YEARWEEK() | برگرداندن ترکیب سال و هفته. |
ADDDATE(date, INTERVAL expr unit) و ADDDATE(expr, days)
وقتی آرگومان دوم به شکل INTERVAL باشد، ADDDATE() مترادف DATE_ADD() است؛ تابع مرتبط SUBDATE() نیز مترادف DATE_SUB() است. در شکل دوم، MySQL آرگومان days را تعداد صحیح روزهایی در نظر میگیرد که باید به تاریخ افزوده شوند.
mysql> SELECT DATE_ADD('1998-01-02', INTERVAL 31 DAY);
-- 1998-02-02
mysql> SELECT ADDDATE('1998-01-02', INTERVAL 31 DAY);
-- 1998-02-02
mysql> SELECT ADDDATE('1998-01-02', 31);
-- 1998-02-02
ADDTIME(expr1, expr2)
ADDTIME() مقدار expr2 را به expr1 میافزاید. آرگومان نخست عبارت زمان یا تاریخوزمان و آرگومان دوم عبارت زمان است.
mysql> SELECT ADDTIME('1997-12-31 23:59:59.999999','1 1:1:1.000002');
-- 1998-01-02 01:01:01.000001
CONVERT_TZ(dt, from_tz, to_tz)
این تابع مقدار تاریخوزمان dt را از منطقهٔ زمانی from_tz به to_tz تبدیل میکند. اگر آرگومانها نامعتبر باشند، NULL برمیگرداند.
mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET');
-- 2004-01-01 13:00:00
mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');
-- 2004-01-01 22:00:00
CURDATE() و CURRENT_DATE
CURDATE() تاریخ جاری را، بسته به بافت رشتهای یا عددی، به صورت YYYY-MM-DD یا YYYYMMDD برمیگرداند. CURRENT_DATE و CURRENT_DATE() مترادف آن هستند.
mysql> SELECT CURDATE();
-- 1997-12-15
mysql> SELECT CURDATE() + 0;
-- 19971215
CURTIME() و CURRENT_TIME
CURTIME() زمان جاری را در منطقهٔ زمانی فعلی به صورت HH:MM:SS یا در بافت عددی به صورت HHMMSS برمیگرداند. CURRENT_TIME و CURRENT_TIME() مترادف آن هستند.
mysql> SELECT CURTIME();
-- 23:50:26
mysql> SELECT CURTIME() + 0;
-- 235026
CURRENT_TIMESTAMP و NOW()
CURRENT_TIMESTAMP و CURRENT_TIMESTAMP() مترادف NOW() هستند. NOW() تاریخ و زمان جاری را در قالب رشتهای یا عددی و در منطقهٔ زمانی جاری برمیگرداند.
mysql> SELECT NOW();
-- 1997-12-15 23:50:26
DATE(expr)
بخش تاریخ را از یک عبارت تاریخ یا تاریخوزمان استخراج میکند.
mysql> SELECT DATE('2003-12-31 01:02:03');
-- 2003-12-31
DATEDIFF(expr1, expr2)
اختلاف expr1 و expr2 را بر حسب روز برمیگرداند. هر دو آرگومان میتوانند تاریخ یا تاریخوزمان باشند، اما فقط بخش تاریخ آنها در محاسبه استفاده میشود.
mysql> SELECT DATEDIFF('1997-12-31 23:59:59','1997-12-30');
-- 1
DATE_ADD(date, INTERVAL expr unit) و DATE_SUB(date, INTERVAL expr unit)
این دو تابع محاسبات تاریخ را انجام میدهند. date یک مقدار DATE یا DATETIME و نقطهٔ شروع است. expr مقدار بازهای است که افزوده یا کم میشود و میتواند با علامت منفی آغاز شود. unit واحد تفسیر بازه است. کلیدواژهٔ INTERVAL و نام واحد نسبت به بزرگی و کوچکی حروف حساس نیستند.
| unit | قالب مورد انتظار expr |
MICROSECOND | MICROSECONDS |
SECOND | SECONDS |
MINUTE | MINUTES |
HOUR | HOURS |
DAY | DAYS |
WEEK | WEEKS |
MONTH | MONTHS |
QUARTER | QUARTERS |
YEAR | YEARS |
SECOND_MICROSECOND | 'SECONDS.MICROSECONDS' |
MINUTE_MICROSECOND | 'MINUTES.MICROSECONDS' |
MINUTE_SECOND | 'MINUTES:SECONDS' |
HOUR_MICROSECOND | 'HOURS.MICROSECONDS' |
HOUR_SECOND | 'HOURS:MINUTES:SECONDS' |
HOUR_MINUTE | 'HOURS:MINUTES' |
DAY_MICROSECOND | 'DAYS.MICROSECONDS' |
DAY_SECOND | 'DAYS HOURS:MINUTES:SECONDS' |
DAY_MINUTE | 'DAYS HOURS:MINUTES' |
DAY_HOUR | 'DAYS HOURS' |
YEAR_MONTH | 'YEARS-MONTHS' |
متن منبع یادآور میشود که واحدهای QUARTER و WEEK از MySQL 5.0.0 در دسترساند.
mysql> SELECT DATE_ADD('1997-12-31 23:59:59', INTERVAL '1:1' MINUTE_SECOND);
-- 1998-01-01 00:01:00
mysql> SELECT DATE_ADD('1999-01-01', INTERVAL 1 HOUR);
-- 1999-01-01 01:00:00
DATE_FORMAT(date, format)
تاریخ را بر اساس رشتهٔ قالب مشخص قالببندی میکند. پیش از نویسهٔ قالب باید % قرار گیرد.
| مشخصه | معنا |
%a | نام کوتاه روز هفته، مانند Sun..Sat. |
%b | نام کوتاه ماه، مانند Jan..Dec. |
%c | شمارهٔ ماه، ۰ تا ۱۲. |
%D | روز ماه همراه پسوند انگلیسی مانند 1st و 2nd. |
%d | روز ماه، ۰۰ تا ۳۱. |
%e | روز ماه، ۰ تا ۳۱. |
%f | میکروثانیه، 000000..999999. |
%H | ساعت، ۰۰ تا ۲۳. |
%h, %I | ساعت، ۰۱ تا ۱۲. |
%i | دقیقه، ۰۰ تا ۵۹. |
%j | روز سال، ۰۰۱ تا ۳۶۶. |
%k | ساعت، ۰ تا ۲۳. |
%l | ساعت، ۱ تا ۱۲. |
%M | نام کامل ماه. |
%m | شمارهٔ ماه، ۰۰ تا ۱۲. |
%p | AM یا PM. |
%r | زمان ۱۲ساعته همراه AM/PM. |
%S, %s | ثانیه، ۰۰ تا ۵۹. |
%T | زمان ۲۴ساعته hh:mm:ss. |
%U | هفته ۰۰ تا ۵۳، با یکشنبه بهعنوان نخستین روز هفته. |
%u | هفته ۰۰ تا ۵۳، با دوشنبه بهعنوان نخستین روز هفته. |
%V | هفته ۰۱ تا ۵۳ با آغاز یکشنبه؛ همراه %X. |
%v | هفته ۰۱ تا ۵۳ با آغاز دوشنبه؛ همراه %x. |
%W | نام کامل روز هفته. |
%w | شمارهٔ روز هفته، ۰=یکشنبه تا ۶=شنبه. |
%X | سال چهاررقمی هفتههایی با آغاز یکشنبه؛ همراه %V. |
%x | سال چهاررقمی هفتههایی با آغاز دوشنبه؛ همراه %v. |
%Y | سال چهاررقمی. |
%y | سال دورقمی. |
%% | نویسهٔ % بهصورت Literal. |
%x برای نویسهٔ دیگر | در متن منبع: نمایش خود x برای نویسهای که در فهرست بالا نیست. |
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
-- Saturday October 1997
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%H %k %I %r %T %S %w');
-- 22 22 10 10:23:00 PM 22:23:00 00 6
DATE_SUB، DAY، DAYNAME، DAYOFMONTH، DAYOFWEEK و DAYOFYEAR
DATE_SUB() مشابه DATE_ADD() است اما بازه را کم میکند. DAY() مترادف DAYOFMONTH() است. توابع بعدی نام روز، روز ماه، شاخص روز هفته و روز سال را برمیگردانند.
mysql> SELECT DAYNAME('1998-02-05');
-- Thursday
mysql> SELECT DAYOFMONTH('1998-02-03');
-- 3
mysql> SELECT DAYOFWEEK('1998-02-03');
-- 3 (1=Sunday ... 7=Saturday)
mysql> SELECT DAYOFYEAR('1998-02-03');
-- 34
EXTRACT(unit FROM date)
EXTRACT() از همان واحدهای DATE_ADD() و DATE_SUB() استفاده میکند، اما بهجای انجام محاسبهٔ تاریخ، بخش موردنظر را استخراج میکند.
mysql> SELECT EXTRACT(YEAR FROM '1999-07-02');
-- 1999
mysql> SELECT EXTRACT(YEAR_MONTH FROM '1999-07-02 01:02:03');
-- 199907
FROM_DAYS(N)
شمارهٔ روز N را به مقدار DATE تبدیل میکند. منبع هشدار میدهد که برای تاریخهای پیش از تقویم گریگوری (۱۵۸۲) با احتیاط استفاده شود.
mysql> SELECT FROM_DAYS(729669);
-- 1997-10-07
FROM_UNIXTIME(unix_timestamp [, format])
برچسب زمانی Unix را در منطقهٔ زمانی جاری به نمایش تاریخوزمان تبدیل میکند. بدون قالب، خروجی در بافت رشتهای به صورت YYYY-MM-DD HH:MM:SS است؛ با آرگومان format از همان مشخصههای DATE_FORMAT() استفاده میشود.
mysql> SELECT FROM_UNIXTIME(875996580);
-- 1997-10-04 22:23:00
HOUR(time)
بخش ساعت را برمیگرداند. برای زمان روزانه معمولاً ۰ تا ۲۳ است، اما چون نوع TIME میتواند دامنهٔ بزرگتری داشته باشد، خروجی HOUR() نیز ممکن است از ۲۳ بیشتر شود.
mysql> SELECT HOUR('10:05:03');
-- 10
LAST_DAY(date)
آخرین روز ماه متناظر با تاریخ یا تاریخوزمان را برمیگرداند؛ آرگومان نامعتبر باعث خروجی NULL میشود.
mysql> SELECT LAST_DAY('2003-02-05');
-- 2003-02-28
LOCALTIME و LOCALTIMESTAMP
LOCALTIME، LOCALTIME()، LOCALTIMESTAMP و LOCALTIMESTAMP() همگی در متن منبع مترادف NOW() معرفی شدهاند.
MAKEDATE(year, dayofyear)
از سال و شمارهٔ روز سال یک تاریخ میسازد. dayofyear باید بزرگتر از صفر باشد؛ در غیر این صورت نتیجه NULL است.
mysql> SELECT MAKEDATE(2001,31), MAKEDATE(2001,32);
-- '2001-01-31', '2001-02-01'
MAKETIME(hour, minute, second)
از ساعت، دقیقه و ثانیه یک مقدار زمان ایجاد میکند.
mysql> SELECT MAKETIME(12,15,30);
-- '12:15:30'
MICROSECOND(expr)، MINUTE(time)، MONTH(date) و MONTHNAME(date)
mysql> SELECT MICROSECOND('12:00:00.123456');
-- 123456
mysql> SELECT MINUTE('98-02-03 10:05:03');
-- 5
mysql> SELECT MONTH('1998-02-03');
-- 2
mysql> SELECT MONTHNAME('1998-02-05');
-- February
MICROSECOND() عددی بین ۰ و ۹۹۹۹۹۹، MINUTE() عددی بین ۰ و ۵۹، MONTH() شمارهٔ ماه در بازهٔ ۰ تا ۱۲ و MONTHNAME() نام کامل ماه را برمیگرداند.
PERIOD_ADD(P,N) و PERIOD_DIFF(P1,P2)
PERIOD_ADD() تعداد N ماه را به دورهٔ P با قالب YYMM یا YYYYMM میافزاید و خروجی YYYYMM است. PERIOD_DIFF() تعداد ماه میان دو دوره را محاسبه میکند. منبع تأکید میکند که این آرگومانهای دوره، خودِ مقدار تاریخ نیستند.
mysql> SELECT PERIOD_ADD(9801,2);
-- 199803
mysql> SELECT PERIOD_DIFF(9802,199703);
-- 11
QUARTER(date)
فصل سال را با عدد ۱ تا ۴ برمیگرداند.
mysql> SELECT QUARTER('98-04-01');
-- 2
SECOND(time) و SEC_TO_TIME(seconds)
SECOND() ثانیه را در بازهٔ ۰ تا ۵۹ برمیگرداند. SEC_TO_TIME() تعداد ثانیه را به ساعت، دقیقه و ثانیه تبدیل میکند.
mysql> SELECT SECOND('10:05:03');
-- 3
mysql> SELECT SEC_TO_TIME(2378);
-- 00:39:38
STR_TO_DATE(str, format)
عمل معکوس DATE_FORMAT() را انجام میدهد. رشتهٔ ورودی را بر اساس قالب میخواند و بسته به اجزای موجود، DATETIME، DATE یا TIME برمیگرداند.
mysql> SELECT STR_TO_DATE('04/31/2004', '%m/%d/%Y');
-- 2004-04-31
SUBDATE(date, INTERVAL expr unit) و SUBDATE(expr, days)
در شکل INTERVAL، SUBDATE() مترادف DATE_SUB() است.
mysql> SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
-- 1997-12-02
mysql> SELECT SUBDATE('1998-01-02', INTERVAL 31 DAY);
-- 1997-12-02
SUBTIME(expr1, expr2)
expr2 را از expr1 کم میکند و نتیجه را در قالب آرگومان نخست برمیگرداند.
mysql> SELECT SUBTIME('1997-12-31 23:59:59.999999','1 1:1:1.000002');
-- 1997-12-30 22:58:58.999997
SYSDATE()
تاریخ و زمان جاری را در زمان اجرای تابع، در قالب رشتهای یا عددی، برمیگرداند.
mysql> SELECT SYSDATE();
-- 2006-04-12 13:47:44
TIME(expr)
بخش زمان را از عبارت زمان یا تاریخوزمان استخراج و به صورت رشته برمیگرداند.
mysql> SELECT TIME('2003-12-31 01:02:03');
-- 01:02:03
TIMEDIFF(expr1, expr2)
اختلاف دو آرگومان زمان یا دو آرگومان تاریخوزمان را برمیگرداند؛ هر دو باید از یک نوع باشند.
mysql> SELECT TIMEDIFF('1997-12-31 23:59:59.000001','1997-12-30 01:01:01.000002');
-- 46:58:57.999999
TIMESTAMP(expr) و TIMESTAMP(expr1, expr2)
با یک آرگومان، عبارت تاریخ یا تاریخوزمان را به مقدار تاریخوزمان تبدیل میکند. با دو آرگومان، عبارت زمانی expr2 را به تاریخ/تاریخوزمان expr1 میافزاید.
mysql> SELECT TIMESTAMP('2003-12-31');
-- 2003-12-31 00:00:00
TIMESTAMPADD(unit, interval, datetime_expr)
عدد صحیح interval را در واحد تعیینشده به datetime_expr میافزاید. واحدهای مجاز طبق متن منبع: FRAC_SECOND، SECOND، MINUTE، HOUR، DAY، WEEK، MONTH، QUARTER و YEAR. میتوان پیشوند SQL_TSI_ را نیز به واحد افزود.
mysql> SELECT TIMESTAMPADD(MINUTE,1,'2003-01-02');
-- 2003-01-02 00:01:00
TIMESTAMPDIFF(unit, datetime_expr1, datetime_expr2)
اختلاف صحیح بین دو عبارت تاریخوزمان را در واحد مشخص برمیگرداند؛ واحدهای مجاز همان واحدهای TIMESTAMPADD() هستند.
mysql> SELECT TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');
-- 3
TIME_FORMAT(time, format)
مانند DATE_FORMAT() است، اما رشتهٔ قالب فقط باید مشخصههای ساعت، دقیقه و ثانیه را داشته باشد. اگر بخش ساعت مقدار زمان از ۲۳ بیشتر باشد، %H و %k همان مقدار بزرگتر را نشان میدهند؛ دیگر مشخصههای ساعت مقدار را پیمانهٔ ۱۲ نمایش میدهند.
mysql> SELECT TIME_FORMAT('100:00:00', '%H %k %h %I %l');
-- 100 100 04 04 4
TIME_TO_SEC(time)
mysql> SELECT TIME_TO_SEC('22:23:00');
-- 80580
مقدار زمان را به تعداد ثانیه تبدیل میکند.
TO_DAYS(date)
برای یک تاریخ، شمارهٔ روز از سال صفر را برمیگرداند.
mysql> SELECT TO_DAYS(950501);
-- 728779
UNIX_TIMESTAMP() و UNIX_TIMESTAMP(date)
بدون آرگومان، تعداد ثانیههای سپریشده از 1970-01-01 00:00:00 UTC را بهصورت عدد صحیح بدون علامت برمیگرداند. با آرگومان تاریخ، همان تاریخ را به تعداد ثانیه از مبدأ Unix تبدیل میکند. آرگومان میتواند رشتهٔ DATE، DATETIME، TIMESTAMP یا عددی با قالب YYMMDD/YYYYMMDD باشد.
mysql> SELECT UNIX_TIMESTAMP();
-- 882226357
mysql> SELECT UNIX_TIMESTAMP('1997-10-04 22:23:00');
-- 875996580
UTC_DATE، UTC_TIME و UTC_TIMESTAMP
این توابع بهترتیب تاریخ، زمان، و تاریخوزمان جاری UTC را در بافت رشتهای یا عددی برمیگردانند.
mysql> SELECT UTC_DATE(), UTC_DATE() + 0;
-- 2003-08-14, 20030814
mysql> SELECT UTC_TIME(), UTC_TIME() + 0;
-- 18:07:53, 180753
mysql> SELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0;
-- 2003-08-14 18:08:04, 20030814180804
WEEK(date [, mode])
شمارهٔ هفته را برمیگرداند. شکل دوآرگومانی مشخص میکند هفته از یکشنبه یا دوشنبه آغاز شود و بازهٔ خروجی ۰ تا ۵۳ یا ۱ تا ۵۳ باشد. اگر mode حذف شود، مقدار متغیر سیستمی default_week_format بهکار میرود.
| mode | روز اول هفته | بازه | تعریف هفتهٔ ۱ |
| 0 | Sunday | 0–53 | هفتهای که در این سال یک یکشنبه دارد. |
| 1 | Monday | 0–53 | هفتهای با بیش از ۳ روز در این سال. |
| 2 | Sunday | 1–53 | هفتهای که در این سال یک یکشنبه دارد. |
| 3 | Monday | 1–53 | هفتهای با بیش از ۳ روز در این سال. |
| 4 | Sunday | 0–53 | هفتهای با بیش از ۳ روز در این سال. |
| 5 | Monday | 0–53 | هفتهای که در این سال یک دوشنبه دارد. |
| 6 | Sunday | 1–53 | هفتهای با بیش از ۳ روز در این سال. |
| 7 | Monday | 1–53 | هفتهای که در این سال یک دوشنبه دارد. |
mysql> SELECT WEEK('1998-02-20');
-- 7
WEEKDAY(date)
شاخص روز هفته را برمیگرداند: ۰ برای دوشنبه تا ۶ برای یکشنبه.
mysql> SELECT WEEKDAY('1998-02-03 22:23:00');
-- 1
WEEKOFYEAR(date)
هفتهٔ تقویمی تاریخ را در بازهٔ ۱ تا ۵۳ برمیگرداند و طبق منبع معادل WEEK(date,3) است.
mysql> SELECT WEEKOFYEAR('1998-02-20');
-- 8
YEAR(date) و YEARWEEK(date [, mode])
YEAR() سال را در بازهٔ ۱۰۰۰ تا ۹۹۹۹ برمیگرداند و برای «تاریخ صفر» مقدار ۰ میدهد. YEARWEEK() سال و هفته را برمیگرداند و آرگومان mode همان رفتار WEEK() را دارد. برای نخستین و آخرین هفتهٔ سال ممکن است سال خروجی با سال موجود در تاریخ ورودی متفاوت باشد.
mysql> SELECT YEAR('98-02-03');
-- 1998
mysql> SELECT YEARWEEK('1987-01-01');
-- 198653
متن منبع یادآور میشود که شمارهٔ هفتهٔ YEARWEEK() میتواند با مقداری که WEEK() با حالتهای ۰ یا ۱ میدهد متفاوت باشد.
جدولهای موقت SQL
بعضی RDBMSها از جدول موقت پشتیبانی میکنند. جدول موقت امکان نگهداری و پردازش نتایج میانی را با همان امکانات انتخاب، بهروزرسانی و JOIN (پیوند) جدولهای معمولی فراهم میکند. نکتهٔ مهم این است که جدول موقت با پایان نشست فعلی کلاینت حذف میشود.
طبق متن منبع، جدولهای موقت از MySQL 3.23 به بعد در دسترساند. در نسخههای قدیمیتر میتوان از جدولهای heap استفاده کرد. در یک اسکریپت PHP، جدول موقت با پایان اجرای اسکریپت از بین میرود؛ در برنامهٔ کلاینت MySQL تا زمان بستن کلاینت یا حذف دستی جدول باقی میماند.
mysql> CREATE TEMPORARY TABLE SALESSUMMARY (
-> product_name VARCHAR(50) NOT NULL,
-> total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00,
-> avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00,
-> total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);
mysql> INSERT INTO SALESSUMMARY
-> (product_name, total_sales, avg_unit_price, total_units_sold)
-> VALUES
-> ('cucumber', 100.25, 90, 2);
mysql> SELECT * FROM SALESSUMMARY;
+--------------+-------------+----------------+------------------+
| product_name | total_sales | avg_unit_price | total_units_sold |
+--------------+-------------+----------------+------------------+
| cucumber | 100.25 | 90.00 | 2 |
+--------------+-------------+----------------+------------------+
متن منبع میگوید جدول موقت در خروجی معمول SHOW TABLES فهرست نمیشود و پس از خروج از نشست MySQL دیگر موجود نیست.
حذف جدول موقت
MySQL هنگام بستهشدن اتصال جدول موقت را خودکار حذف میکند، اما میتوان آن را پیش از پایان نشست با DROP TABLE حذف کرد:
mysql> DROP TABLE SALESSUMMARY;
mysql> SELECT * FROM SALESSUMMARY;
ERROR 1146: Table 'TUTORIALS.SALESSUMMARY' doesn't exist
کپی دقیق جدول (Clone Table) در SQL
گاهی لازم است یک کپی دقیق از جدول ساخته شود و CREATE TABLE ... SELECT... کافی نیست، زیرا کپی باید ایندکسها، مقدارهای پیشفرض و سایر اجزای ساختار را نیز داشته باشد. متن منبع برای MySQL این مراحل را پیشنهاد میکند:
- با
SHOW CREATE TABLE دستور ساخت کامل جدول مبدا، شامل ساختار و ایندکسها، را دریافت کنید.
- نام جدول را در دستور به نام جدول کپی تغییر دهید و دستور را اجرا کنید.
- در صورت نیاز به کپی دادهها،
INSERT INTO ... SELECT را نیز اجرا کنید.
مرحلهٔ ۱: دریافت ساختار
SQL> SHOW CREATE TABLE TUTORIALS_TBL \G;
*************************** 1. row ***************************
Table: TUTORIALS_TBL
Create Table: CREATE TABLE `TUTORIALS_TBL` (
`tutorial_id` int(11) NOT NULL auto_increment,
`tutorial_title` varchar(100) NOT NULL default '',
`tutorial_author` varchar(40) NOT NULL default '',
`submission_date` date default NULL,
PRIMARY KEY (`tutorial_id`),
UNIQUE KEY `AUTHOR_INDEX` (`tutorial_author`)
) TYPE=MyISAM
مرحلهٔ ۲: ساخت جدول کپی
SQL> CREATE TABLE `CLONE_TBL` (
-> `tutorial_id` int(11) NOT NULL auto_increment,
-> `tutorial_title` varchar(100) NOT NULL default '',
-> `tutorial_author` varchar(40) NOT NULL default '',
-> `submission_date` date default NULL,
-> PRIMARY KEY (`tutorial_id`),
-> UNIQUE KEY `AUTHOR_INDEX` (`tutorial_author`)
-> ) TYPE=MyISAM;
مرحلهٔ ۳: کپی دادهها
SQL> INSERT INTO CLONE_TBL (tutorial_id,
-> tutorial_title,
-> tutorial_author,
-> submission_date)
-> SELECT tutorial_id, tutorial_title,
-> tutorial_author, submission_date
-> FROM TUTORIALS_TBL;
پس از این سه مرحله، جدول کپی دارای ساختار و در صورت اجرای مرحلهٔ سوم دارای دادههای جدول مبدا است.
زیرپرسوجو (Subquery) در SQL
Subquery (زیرپرسوجو)، پرسوجوی داخلی یا پرسوجوی تودرتو، پرسوجویی درون یک پرسوجوی SQL دیگر است. زیرپرسوجو دادهای را برمیگرداند که پرسوجوی اصلی از آن بهعنوان شرطی برای محدودترکردن دادهٔ قابل بازیابی استفاده میکند.
زیرپرسوجوها میتوانند همراه SELECT، INSERT، UPDATE و DELETE و عملگرهایی مانند =، <، >، >=، <=، IN و BETWEEN استفاده شوند.
قواعد زیرپرسوجو
- زیرپرسوجو باید داخل پرانتز باشد.
- معمولاً فقط یک ستون در
SELECT زیرپرسوجو وجود دارد، مگر آنکه پرسوجوی اصلی چند ستون را برای مقایسه در نظر گرفته باشد.
ORDER BY در زیرپرسوجو قابل استفاده نیست، هرچند پرسوجوی اصلی میتواند آن را داشته باشد؛ متن منبع GROUP BY را برای هدف مشابه در زیرپرسوجو ذکر میکند.
- زیرپرسوجویی که بیش از یک سطر برمیگرداند فقط با عملگرهای چندمقداری مانند
IN استفاده میشود.
- فهرست
SELECT نباید به مقادیری ارجاع دهد که نوع BLOB، ARRAY، CLOB یا NCLOB ارزیابی میشوند.
- زیرپرسوجو نمیتواند بلافاصله داخل یک تابع مجموعهای محصور شود.
- عملگر
BETWEEN نمیتواند با خود زیرپرسوجو استفاده شود، اما میتواند داخل زیرپرسوجو قرار گیرد.
زیرپرسوجو با SELECT
SELECT column_name [, column_name ]
FROM table1 [, table2 ]
WHERE column_name OPERATOR
(SELECT column_name [, column_name ]
FROM table1 [, table2 ]
[WHERE]);
نمونه، مشتریانی را انتخاب میکند که حقوق آنها بیش از ۴۵۰۰ است:
SQL> SELECT *
FROM CUSTOMERS
WHERE ID IN (SELECT ID
FROM CUSTOMERS
WHERE SALARY > 4500);
+----+----------+-----+---------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+---------+----------+
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 7 | Muffy | 24 | Indore | 10000.00 |
+----+----------+-----+---------+----------+
زیرپرسوجو با INSERT
INSERT میتواند دادهٔ برگرداندهشده از یک زیرپرسوجو را در جدول دیگری درج کند. دادهٔ انتخابشده میتواند با توابع نویسهای، تاریخ یا عددی تغییر کند.
INSERT INTO table_name [ (column1 [, column2 ]) ]
SELECT [ *|column1 [, column2 ]
FROM table1 [, table2 ]
[ WHERE VALUE OPERATOR ];
برای کپی جدول CUSTOMERS به جدول همساختار CUSTOMERS_BKP:
SQL> INSERT INTO CUSTOMERS_BKP
SELECT * FROM CUSTOMERS
WHERE ID IN (SELECT ID
FROM CUSTOMERS);
زیرپرسوجو با UPDATE
با زیرپرسوجو میتوان یک یا چند ستون را در UPDATE تغییر داد.
UPDATE table
SET column_name = new_value
[ WHERE OPERATOR [ VALUE ]
(SELECT COLUMN_NAME
FROM TABLE_NAME)
[ WHERE) ];
در مثال منبع، با فرض وجود CUSTOMERS_BKP، حقوق مشتریانی که سنشان دستکم ۲۷ است در 0.25 ضرب میشود:
SQL> UPDATE CUSTOMERS
SET SALARY = SALARY * 0.25
WHERE AGE IN (SELECT AGE FROM CUSTOMERS_BKP
WHERE AGE >= 27);
طبق نتیجهٔ منبع، دو سطر تحت تأثیر قرار میگیرند؛ Ramesh و Hardik در جدول نهایی بهترتیب حقوق 125.00 و 2125.00 دارند، در حالی که دیگر سطرها مطابق نمونه باقی میمانند.
زیرپرسوجو با DELETE
DELETE FROM TABLE_NAME
[ WHERE OPERATOR [ VALUE ]
(SELECT COLUMN_NAME
FROM TABLE_NAME)
[ WHERE) ];
مثال منبع رکورد مشتریانی را که سنشان بزرگتر از ۲۷ است بر اساس جدول پشتیبان حذف میکند:
SQL> DELETE FROM CUSTOMERS
WHERE AGE IN (SELECT AGE FROM CUSTOMERS_BKP
WHERE AGE > 27);
+----+---------+-----+---------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+---------+-----+---------+----------+
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali| 25 | Mumbai | 6500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
| 7 | Muffy | 24 | Indore | 10000.00 |
+----+---------+-----+---------+----------+