Leetcode数据库(MySQL)常用的函数
日期函数
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) |
%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 位 |
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)
- period: 期间应采用YYMM或YYYYMM格式
- number: 将添加到给定期间的月数,该值可以是负数或正数
图片链接
LeetCode 1843 可疑银行账户
参考解法
extract()
字符串操作
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
参考解答