MySQL學習筆記之八 操作日期和時間

    日期和時間類型是DATETIME、DATE、TIMESTAMP、TIME和YEAR。這些的每一個都有合法值的一個範圍,而“零”當你指定確實不合法的值時被使用。注意,MySQL允許你存儲某個“不嚴格地”合法的日期值,例如1999-11-31,原因我們認爲它是應用程序的責任來處理日期檢查,而不是SQL服務器。爲了使日期檢查更“快”,MySQL僅檢查月份在0-12的範圍,天在0-31的範圍。上述範圍這樣被定義是因爲MySQL允許你在一個DATE或DATETIME列中存儲日期,這裏的天或月是零。這對存儲你不知道準確的日期的一個生日的應用程序來說是極其有用的,在這種情況下,你簡單地存儲日期象1999-00-00或1999-01-00。(當然你不能期望從函數如DATE_SUB()或DATE_ADD()得到類

似以這些日期的正確值)。

    一、返回當前日期和時間

    通過函數GETDATE(),你可以獲得當前的日期和時間。例如,
    CURDATE() 返回當前日期
    CURRENT_DATE
    以'YYYY-MM-DD'或YYYYMMDD格式返回今天日期值,取決於函數是在一個字符串還是數字上下文被使用。
    mysql> select CURDATE();

    mysql> select CURDATE() + 0;

    CURTIME() 返回當前時間
    以'HH:MM:SS'或HHMMSS格式返回當前時間值,取決於函數是在一個字符串還是在數字的上下文被使用。
    mysql> select CURTIME();

    mysql> select CURTIME() + 0;

    NOW() 返回當前時期和時間
    NOW()以YYYY-MM-DD HH:MM:SS的格式或者YYYYMMDDHHMMSS的格式返回日期和時間值,取決於上下文。
    mysql>select now();

    這些得到當前日期和時間的函數,對於日期和時間的計算很方便,尤其是計算一個時間到現在的時間差。例如,在student表中,我們以天爲單位計算學生的年齡:
    mysql> SELECT name,CURDATE()-birth FROM students;

    二、自動記錄數據的改變時間

    TIMESTAMP列類型提供一種類型,TIMESTAMP值可以從1970的某時的開始一直到2037年,精度爲一秒,其值作爲數字顯示。你可以使用它自動地用當前的日期

和時間標記INSERT或UPDATE的操作。如果你有多個TIMESTAMP列,只有第一個自動更新
    自動更新第一個TIMESTAMP列在下列任何條件下發生:

  •     列沒有明確地在一個INSERT或LOAD DATA INFILE語句中指定。
  •     列沒有明確地在一個UPDATE語句中指定且一些另外的列改變值。(注意一個UPDATE設置一個列爲它已經有的值,這將不引起TIMESTAMP列被更新,因爲如果你設  置一個列爲它當前的值,MySQL爲了效率而忽略更改。)
  •     你明確地設定TIMESTAMP列爲NULL.

    除第一個以外的TIMESTAMP列也可以設置到當前的日期和時間,只要將列設爲NULL,或NOW()。

mysql> CREATE TABLE student
-> (
-> id int,
-> name char(16),
-> english tinyint,
-> chinese tinyint,
-> history tinyint,
-> time timestamp
-> );
    向表中插入記錄,可以查看效果:
    mysql> INSERT student(id,name,englisht,Chinese,history) VALUES(11,”Tom”,66,93,67);
    查看記錄的存儲情況:
    mysql> SELECT * FROM student;

    +------+---------+---------+---------+---------+----------------+
    | id | name | english | chinese | history | time |
    +------+---------+---------+---------+---------+----------------+
    | 11 | Tom | 66 | 93 | 67 | 20010220123335 |
    +------+---------+---------+---------+---------+----------------+

    你可以看到time列紀錄下了數據錄入時的時間值。如果你更新改記錄,在查看操作的結果:
    mysql> UPDATE student SET english=76 WHERE id=11;
    mysql> SELECT * FROM student;
    +------+------+---------+---------+---------+----------------+
    | id | name | english | chinese | history | time |
    +------+------+---------+---------+---------+----------------+
    | 11 | Tom | 76 | 93 | 67 | 20010220125736 |
    +------+------+---------+---------+---------+----------------+
    可以清楚的看到,time列的時間被自動更改爲修改記錄的時間。
    有時候你希望不更改任何值,也能打到修改TIMESTAMP列的值,這時只要設置該列的值爲NULL,MySQL就可以自動更新TIMESTAMP列的值:
    mysql> UPDATE student SET time=NULL WHERE id=11;
    mysql> select * from student where id=11;
    +------+------+---------+---------+---------+----------------+
    | id | name | english | chinese | history | time |
    +------+------+---------+---------+---------+----------------+
    | 11 | Tom | 76 | 93 | 67 | 20010220130517 |
    +------+------+---------+---------+---------+----------------+
    通過明確地設置希望的值,你可以設置任何TIMESTAMP列爲不同於當前日期和時間的值,即使對第一個TIMESTAMP列也是這樣。例如,如果,當你創建一個行時,你想要一個TIMESTAMP被設置到當前的日期和時間,但在以後無論何時行被更新時都不改變,你可以使用這樣使用:
    讓MySQL在行被創建時設置列,這將初始化它爲當前的日期和時間。
    當你執行隨後的對該行中其他列的更改時,明確設定TIMESTAMP列爲它的當前值。
    例如,當你在修改列時,可以把原有的值付給TIMESTAMP列:
    mysql> UPDATE student SET english=66,time=time WHERE id=11;
    mysql> select * from student where id=11;
    +------+------+---------+---------+---------+----------------+
    | id | name | english | chinese | history | time |
    +------+------+---------+---------+---------+----------------+
    | 11 | Tom | 66 | 93 | 67 | 20010220130517 |
    +------+------+---------+---------+---------+----------------+
    另一方面,你可能發現,當你想要實現上面這個效果時,很容易用一個你用NOW()初始化的DATETIME列然後不再改變它,這樣也許直接些。但是,TIMESTAMP列的以後好處是存儲要求比較小,節省空間。TIMESTAMP的存儲需求是4字節,而DATETIME列的存儲需求是8字節

    三、返回日期和時間範圍

    例如,我要查看日誌表中的日誌時間

    mysql> SELECT * FROM weblog WHERE entrydate="2014-06-05"
    不要這樣做。這個SELECT語句不會返回正確的記錄――它將只返回值爲2014-06-05 00:00:00的記錄,換句話說,只返回當天零點零時的記錄。上面語句的結果爲:
    +----------+---------------------+
    | data | entrydate |
    +----------+---------------------+
    | 0.973723 | 2014-06-05 00:00:00 |
    +----------+---------------------+
    要返回正確的記錄,你需要適用日期和時間範圍,有以下兩種方式:
    1、使用關係運算符和邏輯運算符來限制時間範圍
    例如,下面的這個SELECT 語句將能返回正確的記錄:
    mysql> SELECT * FROM weblog
    -> WHERE entrydate>="2014-06-05" AND entrydate<"2014-06-05" ;
    這個語句可以完成任務,因爲它選取的是表中的日期和時間大於等於2014-06-05 00:00:00並小於2014-06-06 00:00:00的記錄。換句話說,它將正確地返回2014年6月5日這一天輸入的每一條記錄。其結果爲:
    +-----------+---------------------+
    | data | entrydate |
    +-----------+---------------------+
    | 0.973723 | 2014-06-05 00:00:00 |
    | 0.437768 | 2014-06-0513:57:06 |
    | 0.327279 | 2014-06-05 13:57:09 |
    | 0.0931809 | 2014-06-05 13:58:29 |
    | 0.198805 | 2014-06-05 13:57:54 |
    +-----------+---------------------+
    2、另一種方法是,你可以使用LIKE來返回正確的記錄。通過在日期表達式中包含通配符“%”,你可以匹配一個特定日期的所有時間。
    這裏有一個例子:
    mysql> SELECT * FROM weblog WHERE entrydate LIKE '2014-06-05%' ;
    這個語句可以匹配正確的記錄。因爲通配符“”代表了任何時間。
    +-----------+---------------------+
    | data | entrydate |
    +-----------+---------------------+
    | 0.973723 | 2014-06-05 00:00:00 |
    | 0.437768 | 2014-06-05 13:57:06 |
    | 0.327279 | 2014-06-05 13:57:09 |
    | 0.0931809 | 2014-06-05 13:58:29 |
    | 0.198805 | 2014-06-05 13:57:54 |
    +-----------+---------------------+
    3、上面兩種方法的異同
    由於使用關係運算符進行的是比較過程,時轉換成內部的存儲格式後進行的,因此,因此時間的書寫可以不是那麼嚴格要求。
    例如,下面幾種寫法是等價的:
    mysql> SELECT * FROM weblog WHERE entrydate>="2014-06-05";
    mysql> SELECT * FROM weblog WHERE entrydate>="2014-6-5";
    mysql> SELECT * FROM weblog WHERE entrydate>="2014*06*05";
    mysql> SELECT * FROM weblog WHERE entrydate>="20140605";
    SELECT * FROM weblog WHERE entrydate>="2014/6/5";
    而使用LIKE運算符和模式匹配,是通過比較串值進行的,因此必須使用標準的時間書寫格式,YYYY-MM-DD HH-MM-SS。
    四、時間和日期的比較

    已知兩個日期,比較它們的前後,可以直接求出它們的差和零值比較,也可以利用已知的時間函數:
    TO_DAYS(date)
    給出一個日期date,返回一個天數(從0年的天數),date可以是一個數字,也可以是一個串值,當然更可以是包含日期的時間類型。
    mysql> select TO_DAYS(960501);
    +-----------------+
    | TO_DAYS(960501) |
    +-----------------+
    | 729145 |
    +-----------------+
    mysql> select TO_DAYS('1997-07-01');
    +-----------------------+
    | TO_DAYS('1997-07-01') |
    +-----------------------+
    | 729571 |
    +-----------------------+
    例如:返回2個時間相差的天數(21世紀已經過去了多少天)
    mysql> select to_days(now())-to_days('20010101');
    +---------------------------------------------------+
    | to_days(now()-00000012000000)-to_days('20010101') |
    +---------------------------------------------------+
    | 38 |
    +---------------------------------------------------+

發佈了66 篇原創文章 · 獲贊 3 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章