【MySQL】Leetcode刷题--数据库(MySQL)常用的函数及语法

本文详细介绍了MySQL中的日期函数如DATEDIFF、DATE_FORMAT等,字符串操作如TRIM、LOWER,以及WITH AS创建临时表、正则表达式、行转列和列转行的方法,并通过LeetCode题目进行实战演示,帮助读者深入理解MySQL的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

日期函数

datediff()

MySQL 中 DATEDIFF(date1,date2) 返回起始时间 date1 和结束时间 date2 之间的天数。date1 和 date2 为日期或 date-and-time 表达式。计算时只用到这些值的日期部分。

 mysql>SELECT DATEDIFF('2017-11-30','2017-11-29') AS COL1,
-> DATEDIFF('2017-11-30','2017-12-15') AS col2;
+------+------+
| COL1 | col2 |
+------+------+
|  1 | -15 |
+------+------+
1 row in set (0.00 sec)

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)
%pAM 或 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 位

例子 Leetcode 1853
在这里插入图片描述

select date_format(day,"%W, %M %e, %Y") as day
from Days

TimeStampDiff()

计算两日期时间之间相差的天数,秒数,分钟数,周数,小时数,这里主要是通过MySql内置的函数 TimeStampDiff() 实现。

语法如下:

TIMESTAMPDIFF(unit,datetime_expr1,datetime_expr2)

返回日期或日期时间表达式datetime_expr1 和datetime_expr2the 之间的整数差。其中unit单位有如下几种,分别是:FRAC_SECOND (microseconds), SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR 。

示例

 # 计算两日期之间相差多少周
 select timestampdiff(week,'2011-09-30','2015-05-04');
 # 计算两日期之间相差多少天
 select timestampdiff(day,'2011-09-30','2015-05-04');

注意事项:
Leetcode 1939
此题中要求间隔24小时,但是不能用datestampdiff(hour, exp1, exp2),因为datestampdiff返回的是日期间隔的整数,所以即使间隔24小时1分也会返回24小时,所以此题要用second来返回。

period_add()

period_add()在给定期间内加上特定的月份数,period_add()返回YYYYMM形式的日期。

period_add(period, number)

extract()

LeetCode 1843 可疑银行账户
参考解法

字符串操作

trim(), ltrim(), rtrim()

  • trim()可以过滤指定的字符串
    完整格式:TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str)
    简化格式:TRIM([remstr FROM] str)
    若分类符BOTH、LEADIN或TRAILING中没有一个是给定的,则假设为BOTH。remstr为可选项,在未指定情况下,可删除空格。
mysql> SELECT TRIM('  bar   ');
 
    -> 'bar'
 
mysql> SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');   --删除指定的首字符 x
 
    -> 'barxxx'
 
mysql> SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');      --删除指定的首尾字符 x
 
    -> 'bar'
 
mysql> SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');  --删除指定的尾字符 x
 
    -> 'barx'
  • ltrim() 去除左空格函数
mysql> SELECT LTRIM('  barbar');
 
    -> 'barbar'
  • rtrim() 去除右空格函数
mysql> SELECT RTRIM('barbar   ');
 
    -> 'barbar'

引用

lower()和upper()

lower()和lcase()都是将字符全部变为小写
upper()和ucase()都是将字符全部变为大写

select upper('chINese'), lower('chINese'); # CHINESE   chinese
select ucase('chINese'), lcase('chINese'); # CHINESE   chinese

with as创建临时表

with as 创建临时表语法示例:

WITH
  cte1 AS (SELECT a, b FROM table1),
  cte2 AS (SELECT c, d FROM table2)
SELECT b, d FROM cte1 JOIN cte2
WHERE cte1.a = cte2.c;

with recursive as 创建递归临时表

WITH RECURSIVE cte (n) AS
(
  SELECT 1
  UNION ALL
  SELECT n + 1 FROM cte WHERE n < 5
)
SELECT * FROM cte;

LeetCode1613题目示例
LeetCode1613解答

注意事项

  • as后的查询必须加括号,否则会报错;
  • with可以创建多个临时表,只需要用逗号隔开;
  • 用with创建的最后一个临时表后面不需要加分号,分号只需要写在所有SQL的最后;

正则表达式

在这里插入图片描述题目链接

select distinct city from station where city regexp "^[aeiou]" and city regexp "[aeiou]$"

不能写成如下形式:

select distinct city from station where city regexp '^[aeiou]$';

行转列,列转行

Leetcode 1777 行转列示例
Leetcode 1795 列转行示例
行列转换就是如下图所示两种展示形式的互相转换:
(上表/行表:student1;下表/列表:student2)
在这里插入图片描述

行转列

【行转列——MAX/SUM+CASE WHEN+GROUP BY】
SELECT name,
MAX(CASE WHEN subject=‘语文’ THEN score ELSE 0 END) AS “语文”,
MAX(CASE WHEN subject=‘数学’ THEN score ELSE 0 END) AS “数学”,
MAX(CASE WHEN subject=‘英语’ THEN score ELSE 0 END) AS “英语”
FROM student1
GROUP BY name

列转行

【列转行——MAX+UNION+GROUP BY】
SELECT NAME,‘语文’ AS subject,MAX(“语文”) AS score
FROM student2 GROUP BY NAME
UNION
SELECT NAME,‘数学’ AS subject,MAX(“数学”) AS score
FROM student2 GROUP BY NAME
UNION
SELECT NAME,‘英语’ AS subject,MAX(“英语”) AS score
FROM student2 GROUP BY NAME
转自Leetcode解答

窗口函数

格式

[你要的操作] OVER ( PARTITION BY  <用于分组的列名>
                    ORDER BY <按序叠加的列名> 
                    ROWS <窗口滑动的数据范围> )

窗口滑动的数据范围

当前行 - current row
之前的行 - preceding
之后的行 - following
无界限 - unbounded
表示从前面的起点 - unbounded preceding
表示到后面的终点 - unbounded following

例子:

取当前行和前五行:ROWS between 5 preceding and current row --共6行
取当前行和后五行:ROWS between current row and 5 following --共6行
取前五行和后五行:ROWS between 5 preceding and 5 folowing --共11行

其中between … and…,以及current row这些关键字都可以省略
参考题目LeetCode 1321
参考解答

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值