当前位置:首页 > 问答 > 正文

SQL里那个DATENAME函数到底怎么用啊,感觉挺实用但又有点绕

这个函数是干嘛的?

简单打个比方,你有一个日期数据,2023-10-27,这个日期本身对电脑来说就是一串数字,但我们人来看的时候,常常需要关心它的不同侧面:

  • 今年是2023年。
  • 现在是10月。
  • 今天是星期五

DATENAME 函数干的就是这个活儿:你告诉它你想要日期的哪个部分(是年?是月?还是星期几?),它就把那个部分的名字(通常是字符串形式的)给你“报”出来。

函数的基本样子

它的写法通常长这样: DATENAME(datepart, date)

这里有两个关键信息你需要塞给它:

  1. datepart:这就是你想要的“部分”,就是你到底要年、月、日还是其他啥,你需要用特定的单词告诉它,year, month, day, weekday 等,这个是必须要指定的,不能错。
  2. date:这就是你要处理的原始日期,它可以是一个具体的日期值('2023-10-27'),也可以是一个包含日期信息的表里面的列名。

它返回什么?

SQL里那个DATENAME函数到底怎么用啊,感觉挺实用但又有点绕

很重要的一点是,DATENAME 返回的是一个字符串,或者说是一段文本,即使你提取的是“年”这样的数字,它返回的也是 '2023' 这样的文本,而不是可以直接做加减乘除的数字 2023,这一点和另一个类似的函数 DATEPART(它返回整数)是主要区别之一。

具体怎么用?来看例子

假设我们有一个简单的订单表 Orders,里面有一列叫 OrderDate(订单日期),记录着每个订单是哪天创建的。

OrderID OrderDate
1 2023-10-25
2 2023-10-26
3 2023-10-27

例子1:提取年份 如果老板想看看所有订单都是哪一年的,你可以这样写: SELECT DATENAME(year, OrderDate) AS OrderYear FROM Orders; 结果你会得到三行,每一行都是 '2023',这里的 AS OrderYear 是给结果列起个易懂的别名。

SQL里那个DATENAME函数到底怎么用啊,感觉挺实用但又有点绕

例子2:提取月份的名字 这才是 DATENAME 真正显示优势的地方,如果你想知道订单都是在几月份下的,并且希望月份显示成英文全名(October),而不是数字 10SELECT DATENAME(month, OrderDate) AS OrderMonth FROM Orders; 对于上面三条记录,结果都会是 'October',是不是比看数字 10 更直观?需要注意的是,根据数据库的语言设置,返回的月份或星期名称可能是英文、中文等,在中文环境下,可能会返回 '十月'

例子3:提取星期几 你想分析一下订单更喜欢集中在一周中的哪一天,比如是不是周末订单更多。 SELECT DATENAME(weekday, OrderDate) AS OrderWeekday FROM Orders; 对于 2023-10-27,这个函数会返回 'Friday'(如果语言是英文)或 '星期五'(如果语言是中文)。

所有你能“提取”的部分有哪些?

除了上面用到的,datepart 还有很多选项,下面列一些常用的(根据微软官方 Transact-SQL 文档中关于日期部分的说明):

  • year (或缩写 yy, yyyy):年份
  • quarter (缩写 qq, q):季度(返回 1 到 4 的数字字符串,如 '1'
  • month (缩写 mm, m):月份(返回数字或名称,取决于系统)
  • dayofyear (缩写 dy, y):一年中的第几天(1-366)
  • day (缩写 dd, d):一个月中的第几天(1-31)
  • week (缩写 wk, ww):一年中的第几周(1-53)
  • weekday (缩写 dw):星期几(注意:返回的是名称,如 Monday)
  • hour (缩写 hh):小时(0-23)
  • minute (缩写 mi, n):分钟(0-59)
  • second (缩写 ss, s):秒(0-59)

需要注意的“坑”和技巧

  1. 返回的是字符串:再次强调,如果你需要对提取出来的部分进行数学计算(比如计算年龄),用 DATENAME 就不太方便,你得先把字符串转成数字,这种情况下,用 DATEPART 函数更直接,它返回整数。
  2. 语言依赖:月份和星期几的名称取决于数据库的语音设置(SET LANGUAGE),如果你的应用对显示的文字有严格要求,这一点要特别注意。
  3. 处理 NULL 值:如果第二个参数 date 是 NULL(空值),DATENAME 函数返回的结果也是 NULL。
  4. 实际应用:这个函数在生成报表时特别有用,比如你可以写一个查询,将订单按月份分组统计: SELECT DATENAME(month, OrderDate) AS MonthName, COUNT(*) AS OrderCount FROM Orders GROUP BY DATENAME(month, OrderDate); 这样就能清晰地看到每个月的订单数量。

DATENAME 就是一个非常直观的“日期解读器”,你指定位子(datepart),它就从日期(date)里把那个位子的文字描述抠出来给你,多在实际的查询里用几次,结合不同的参数,很快就能熟练掌握了,它的“绕”主要就在于要记清楚那些 datepart 的缩写,以及返回值是文本这个特性。