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

教你搞懂sql里那个DATENAME函数到底咋用,别再迷糊了

你是不是有时候在 SQL 里查数据,看到一堆像 2023-10-25 这样的日期,心里就想:“我光知道这是2023年10月25号,但我要是只想单独拿出‘年’、或者‘月’、甚至是‘星期几’来用,该咋整呢?” 老板让你统计一下每个季度销售额,或者看看周末的订单是不是比工作日多,这时候,DATENAME 函数就是你的大救星。

DATENAME 函数就是个“日期拆解器”,你给它一个日期,再告诉它你想拆出哪个部分(比如年、月、日、星期),它就直接把那个部分的名字或者数字给你“报”出来,注意哦,是“报出来”,意思是它返回的结果通常是一段文字(在数据库里叫字符串),而不是一个可以计算的数字。

这个函数怎么用呢?语法超级简单。

基本上就长这样:DATENAME( datepart , date )

你看,就两个东西需要你塞进去:

  1. datepart: 这就是你指定要拆哪个部分的关键词,你想要年份,就写 year;想要月份,就写 month
  2. date: 这就是你要被拆解的那个日期本身,它可以是一个日期类型的字段名(比如你表里的 create_time 字段),也可以是一个直接用单引号括起来的日期,'2023-10-25'

光说不练假把式,咱们直接看例子,保准你秒懂,假设我们现在有一个日期是 2023-10-25,这是个星期三。

例子1:拆出年份 你写:SELECT DATENAME(year, '2023-10-25') AS 年份; 电脑就会返回给你一个结果:2023 这里的 year 就是告诉函数:“喂,我只要年份部分。”后面的 '2023-10-25' 就是目标日期。AS 年份 是给返回的这列数据起个易懂的别名,方便你看。

例子2:拆出月份 你写:SELECT DATENAME(month, '2023-10-25') AS 月份; 注意啦!这里的结果可能跟你想象的不太一样,它会返回 October,而不是数字 10。 这就是 DATENAME 的一个特点:对于“月”(month)和“星期”(weekday)这类有名字的部分,它默认返回的是英文名称(如果你的数据库语言是英文的话),如果你想得到数字月份,你可能需要换一个函数,DATEPART,这个我们待会儿对比一下。

例子3:拆出星期几 你写:SELECT DATENAME(weekday, '2023-10-25') AS 星期几; 它会返回 Wednesday,看,它把星期几的名字告诉你了。

例子4:拆出一年中的第几天 你写:SELECT DATENAME(dayofyear, '2023-10-25') AS 年内第几天; 它会返回 298,意思是2023年的10月25日是这一年的第298天。

教你搞懂sql里那个DATENAME函数到底咋用,别再迷糊了

常用的 datepart 参数都有啥? 我给你列几个最常用的,你记下来就够使了:

  • yearyyyyyy: 年份
  • quarterqqq: 季度(返回1到4的数字)
  • monthmmm: 月份(返回英文名,如 January)
  • dayddd: 一个月中的第几天(返回数字)
  • weekdaydw: 星期几(返回英文名,如 Monday)
  • weekwkww: 一年中的第几周(返回数字)

你看,同一个部分可能有不同的写法,效果是一样的,选你记得住的用就行。

那它和 DATEPART 函数有啥区别呢? 这俩是亲兄弟,长得像,但脾气不一样,最关键的区别就是:DATENAME 返回的是字符串(文本),而 DATEPART 返回的是整数(数字)

还是用月份来举例:

  • SELECT DATENAME(month, '2023-10-25') 会返回 October
  • SELECT DATEPART(month, '2023-10-25') 会返回 10

那你该用哪个呢?看你的需求!

教你搞懂sql里那个DATENAME函数到底咋用,别再迷糊了

  • 如果你想在报表里直接显示“October 2023”这样好看的名字,就用 DATENAME。
  • 如果你想用月份来做计算、排序或者分组(GROUP BY 月份),那用 DATEPART 得到数字 10 会更方便,因为计算机处理数字比处理文本快得多,也更准确(比如排序时,数字10和11会按顺序排,但文本‘10’和‘11’可能就会出问题)。

实战场景:用它来分组统计 光拆着玩没意思,DATENAME 真正厉害的地方是和 GROUP BY 结合起来做统计,比如你有一张订单表 Orders,里面有个下单时间字段 OrderDate

场景1:统计每年的订单总数 你的 SQL 可以这么写:

SELECT DATENAME(year, OrderDate) AS 订单年份,
       COUNT(*) AS 订单数量
FROM Orders
GROUP BY DATENAME(year, OrderDate);

这样你就会得到类似这样的结果: 订单年份 | 订单数量 --- | --- 2022 | 1500 2023 | 1800

场景2:统计每个季度的销售额 假设还有个 Amount 字段是金额。

SELECT DATENAME(year, OrderDate) AS 年份,
       DATENAME(quarter, OrderDate) AS 季度,
       SUM(Amount) AS 总销售额
FROM Orders
GROUP BY DATENAME(year, OrderDate), DATENAME(quarter, OrderDate)
ORDER BY 年份, 季度;

这样你就能清晰地看到每年每个季度的销售情况,对于做季度复盘超级有用。

最后给你提个醒,避个坑:

  1. 日期格式要正确:你给函数的那个日期,必须是你数据库能认出来的格式,最保险的就是 'YYYY-MM-DD''2023-10-25')。
  2. 注意返回类型:再三记住,DATENAME 拿回来的是文本,如果你需要数字,要么用 DATEPART,要么想办法把 DATENAME 的结果转成数字。
  3. 数据库之间有微小差异:虽然大部分数据库(如 SQL Server)都支持 DATENAME,但像 MySQL 可能用的是 DATE_FORMAT() 函数,Oracle 可能用 TO_CHAR(),思路是一样的,只是函数名和语法稍有不同,用的时候查一下对应数据库的文档就好。

行了,说到这,你应该对 DATENAME 函数门儿清了吧?它就是个简单又实用的工具,下次再遇到需要从日期里“抠”出特定部分的需求,别再迷糊了,大胆用它就行!