SQL 日期
当我们处理日期时,最难的任务恐怕是确保所插入的日期的格式,与数据库中日期列的格式相匹配。
只要数据包含的只是日期部分,运行查询就不会出问题。但是,如果涉及时间,情况就有点复杂了。
在讨论日期查询的复杂性之前,我们先来看看最重要的内建日期处理函数。
MySQL Date 函数
下面的表格列出了 MySQL 中最重要的内建日期函数:
定义和用法 NOW() 函数返回当前的日期和时间。
语法 NOW()
例子 1
SELECT NOW(),CURDATE(),CURTIME()
NOW() CURDATE() CURTIME()
2008-12-29 16:25:46 2008-12-29 16:25:46
例子 2
下面的 SQL 创建带有日期时间列 (OrderDate) 的 "Orders" 表:
CREATE TABLE Orders
(
OrderId int NOT NULL,
ProductName varchar(50) NOT NULL,
OrderDate datetime NOT NULL DEFAULT NOW(),
PRIMARY KEY (OrderId)
)
请注意,OrderDate 列规定 NOW() 作为默认值。作为结果,当您向表中插入行时,当前日期和时间自动插入列中。
现在,我们希望在 "Orders" 表中插入一条新记录:
INSERT INTO Orders (ProductName) VALUES ('Computer')
CURDATE() 函数返回当前的日期。
语法 CURDATE()
CURTIME() 函数返回当前的时间。
语法 CURTIME()
DATE() 函数返回日期或日期/时间表达式的日期部分。
语法 DATE(date)
date 参数是合法的日期表达式。
假设我们有如下的表:
OrderId ProductName OrderDate
1 'Computer' 2008-12-29 16:25:46.635
SELECT ProductName, DATE(OrderDate) AS OrderDate
FROM Orders WHERE OrderId=1
ProductName OrderDate
'Computer' 2008-12-29
EXTRACT() 函数用于返回日期/时间的单独部分,比如年、月、日、小时、分钟等等。
EXTRACT(unit FROM date)
date 参数是合法的日期表达式。unit 参数可以是下列的值:
Unit 值
MICROSECOND
SECOND
MINUTE
HOUR
DAY
WEEK
MONTH
QUARTER
YEAR
SECOND_MICROSECOND
MINUTE_MICROSECOND
MINUTE_SECOND
HOUR_MICROSECOND
HOUR_SECOND
HOUR_MINUTE
DAY_MICROSECOND
DAY_SECOND
DAY_MINUTE
DAY_HOUR
YEAR_MONTH
假设我们有如下的表:
OrderId ProductName OrderDate
1 'Computer' 2008-12-29 16:25:46.635
使用下面的 SELECT 语句:
SELECT EXTRACT(YEAR FROM OrderDate) AS OrderYear,
EXTRACT(MONTH FROM OrderDate) AS OrderMonth,
EXTRACT(DAY FROM OrderDate) AS OrderDay
FROM Orders WHERE OrderId=1
结果:
OrderYear OrderMonth OrderDay
2008 12 29
DATE_ADD() 函数向日期添加指定的时间间隔。
DATE_ADD(date,INTERVAL expr type)
date 参数是合法的日期表达式。expr 参数是您希望添加的时间间隔。
我们希望向 "OrderDate" 添加 2 天,这样就可以找到付款日期。
SELECT OrderId,DATE_ADD(OrderDate,INTERVAL 2 DAY)
AS OrderPayDate FROM Orders
DATE_SUB() 函数从日期减去指定的时间间隔。
DATE_SUB(date,INTERVAL expr type)
我们希望从 "OrderDate" 减去 2 天。
SELECT OrderId,DATE_SUB(OrderDate,INTERVAL 2 DAY)
AS OrderPayDate FROM Orders
DATEDIFF() 函数返回两个日期之间的天数。
DATEDIFF(date1,date2)
date1 和 date2 参数是合法的日期或日期/时间表达式。
注释:只有值的日期部分参与计算。
例子 1 SELECT DATEDIFF('2008-12-30','2008-12-29') AS DiffDate
DiffDate
1
例子 2 SELECT DATEDIFF('2008-12-29','2008-12-30') AS DiffDate
DiffDate
-1
DATE_FORMAT() 函数用于以不同的格式显示日期/时间数据
DATE_FORMAT(date,format)
date 参数是合法的日期。format 规定日期/时间的输出格式。
可以使用的格式有:
格式 描述
%a 缩写星期名
%b 缩写月名
%c 月,数值
%D 带有英文前缀的月中的天
%d 月的天,数值(00-31)
%e 月的天,数值(0-31)
%f 微秒
%H 小时 (00-23)
%h 小时 (01-12)
%I 小时 (01-12)
%i 分钟,数值(00-59)
%j 年的天 (001-366)
%k 小时 (0-23)
%l 小时 (1-12)
%M 月名
%m 月,数值(00-12)
%p AM 或 PM
%r 时间,12-小时(hh:mm:ss AM 或 PM)
%S 秒(00-59)
%s 秒(00-59)
%T 时间, 24-小时 (hh:mm:ss)
%U 周 (00-53) 星期日是一周的第一天
%u 周 (00-53) 星期一是一周的第一天
%V 周 (01-53) 星期日是一周的第一天,与 %X 使用
%v 周 (01-53) 星期一是一周的第一天,与 %x 使用
%W 星期名
%w 周的天 (0=星期日, 6=星期六)
%X 年,其中的星期日是周的第一天,4 位,与 %V 使用
%x 年,其中的星期一是周的第一天,4 位,与 %v 使用
%Y 年,4 位
%y 年,2 位
实例
下面的脚本使用 DATE_FORMAT() 函数来显示不同的格式。我们使用 NOW() 来获得当前的日期/时间:
DATE_FORMAT(NOW(),'%b %d %Y %h:%i %p')
DATE_FORMAT(NOW(),'%m-%d-%Y')
DATE_FORMAT(NOW(),'%d %b %y')
DATE_FORMAT(NOW(),'%d %b %Y %T:%f')
结果类似:
Dec 29 2008 11:45 PM
12-29-2008
29 Dec 08
29 Dec 2008 16:25:46.635
MySQL 使用下列数据类型在数据库中存储日期或日期/时间值:
DATE - 格式 YYYY-MM-DD
DATETIME - 格式: YYYY-MM-DD HH:MM:SS
TIMESTAMP - 格式: YYYY-MM-DD HH:MM:SS
YEAR - 格式 YYYY 或 YY
SQL 日期处理
如果不涉及时间部分,那么我们可以轻松地比较两个日期!
假设我们有下面这个 "Orders" 表:
我们希望从上表中选取 OrderDate 为 "2008-12-26" 的记录。
使用如下 SELECT 语句:
SELECT * FROM Orders WHERE OrderDate='2008-12-26'
提示:如果您希望使查询简单且更易维护,那么请不要在日期中使用时间部分!
SQL NULL 值
NULL 值是遗漏的未知数据。
默认地,表的列可以存放 NULL 值。
本章讲解 IS NULL 和 IS NOT NULL 操作符。
SQL NULL 值
如果表中的某个列是可选的,那么我们可以在不向该列添加值的情况下插入新记录或更新已有的记录。这意味着该字段将以 NULL 值保存。
NULL 值的处理方式与其他值不同。
NULL 用作未知的或不适用的值的占位符。
注释:无法比较 NULL 和 0;它们是不等价的。
看下面的 "Persons" 表:
假如 "Persons" 表中的 "Address" 列是可选的。这意味着如果在 "Address" 列插入一条不带值的记录,"Address" 列会使用 NULL 值保存。
那么我们如何测试 NULL 值呢?
无法使用比较运算符来测试 NULL 值,比如 =, <, 或者 <>。
我们必须使用 IS NULL 和 IS NOT NULL 操作符。
我们如何仅仅选取在 "Address" 列中带有 NULL 值的记录呢?
我们必须使用 IS NULL 操作符:
SELECT LastName,FirstName,Address
FROM Persons WHERE Address IS NULL
提示:请始终使用 IS NULL 来查找 NULL 值。
我们如何选取在 "Address" 列中不带有 NULL 值的记录呢?
我们必须使用 IS NOT NULL 操作符:
SELECT LastName,FirstName,Address FROM Persons
WHERE Address IS NOT NULL
下面的 "Products" 表:
假如 "UnitsOnOrder" 是可选的,而且可以包含 NULL 值。
使用如下 SELECT 语句:
SELECT ProductName,UnitPrice*(UnitsInStock+UnitsOnOrder)
FROM Products
在上面的例子中,如果有 "UnitsOnOrder" 值是 NULL,那么结果是 NULL。
微软的 ISNULL() 函数用于规定如何处理 NULL 值。
NVL(), IFNULL() 和 COALESCE() 函数也可以达到相同的结果。
在这里,我们希望 NULL 值为 0。
下面,如果 "UnitsOnOrder" 是 NULL,则不利于计算,因此如果值是 NULL 则 ISNULL() 返回 0。
MySQL
MySQL 也拥有类似 ISNULL() 的函数。不过它的工作方式与微软的 ISNULL() 函数有点不同。
在 MySQL 中,我们可以使用 IFNULL() 函数,就像这样:
SELECT ProductName,UnitPrice(UnitsInStock+IFNULL(UnitsOnOrder,0))
FROM Products
或者我们可以使用 COALESCE() 函数,就像这样:
SELECT ProductName,UnitPrice(UnitsInStock+COALESCE(UnitsOnOrder,0))
FROM Products