select 语句执行优先级
AND 优先级高于 OR
-- 示例
SELECT *
FROM trx_rcd
WHERE
mch_typ = '餐饮' OR mch_typ = '休闲娱乐' AND trx_amt > 900;
/**
运行时实际的评估顺序是:
1.mch_typ = '休闲娱乐' AND trx_amt > 900 会先被计算
2.然后结果会与 mch_typ = '餐饮' 进行 OR 运算
*/
-- 实际运行时语句为:
SELECT *
FROM trx_rcd
WHERE
mch_typ = '餐饮' OR (mch_typ = '休闲娱乐' AND trx_amt > 900);
-- 若想先判断 "mch_typ = '餐饮' OR mch_typ = '休闲娱乐'",需要将语句修改为:
SELECT *
FROM trx_rcd
WHERE
(mch_typ = '餐饮' OR mch_typ = '休闲娱乐') AND trx_amt > 900;
日期函数
DATE_FORMAT:格式化日期、时间值
-- 函数介绍
-- date: 要格式化的日期或时间值,可以是一个列名、一个字符串或一个日期时间表达式。
-- format: 一个字符串,定义了日期或时间的输出格式
DATE_FORMAT(date, format)
-- format 字符串可以包含多种格式化符号,常见的有:
-- %Y: 四位年份(如 2023)
-- %m: 两位月份(01 到 12)
-- %d: 两位日期(01 到 31)
-- %H: 两位小时(00 到 23)
-- %i: 两位分钟(00 到 59)
-- %s: 两位秒钟(00 到 59)
-- 示例:按 "年-月-日" 格式输出
SELECT DATE_FORMAT('2023-09-07', '%Y-%m-%d') AS formatted_date;
-- 输出
formatted_date|
--------------+
2023-09-07 |
-- 示例:分别提取年、月、日、时、分、秒
SELECT DATE_FORMAT('2023-09-07 14:30:00', '%Y,%m,%d,%H,%i,%s') AS formatted_datetime;
-- 输出
formatted_datetime |
-------------------+
2023,09,07,14,30,00|
DATEDIFF:计算两个日期之间的天数差
-- 函数介绍
-- 用于计算两个日期之间的天数差
-- date1: 第一个日期,通常是结束日期
-- date2: 第二个日期,通常是开始日期
DATEDIFF(date1, date2)
-- 返回一个整数,表示 date1 和 date2 之间的天数差
-- 如果 date1 在 date2 之前,返回的值为负数
-- 示例:计算 当前日期 与 2023-09-30 之间的天数差
SELECT
DATEDIFF('2023-09-30', NOW()) AS `date1 早于 date2`,
DATEDIFF(NOW(), '2023-09-30') AS `date1 晚于 date2`;
-- 输出
date1 早于 date2|date1 晚于 date2|
----------------+----------------+
-343 | 343|
窗口函数
lag()、lead()
函数介绍
lag、lead可以简单看做是相反功能的窗口函数
- lag:主要用于在查询结果集中获取当前行的前几行的数据。
-- 语法
LAG(column_name, offset, default_value) OVER (PARTITION BY partition_column ORDER BY order_column)
-- 参数解释
-- column_name: 要获取行值的列名。
-- offset: 可选参数,指定要向上偏移的行数(默认值为 1)。
-- default_value: 可选参数,当没有前几行时返回的默认值(如果不指定,则返回 NULL)。
-- PARTITION BY: 可选参数,用于将结果集划分为多个部分,LAG 函数将在每个部分内独立工作。
-- ORDER BY: 必须指定,用于定义窗口内行的顺序。
- lead:用于在查询结果集中获取当前行的后几行的数据。
-- 语法
LEAD(column_name, offset, default_value) OVER (PARTITION BY partition_column ORDER BY order_column)
-- 参数解释
-- column_name: 要获取行值的列名。
-- offset: 可选参数,指定要向下偏移的行数(默认值为 1)。
-- default_value: 可选参数,当没有后几行时返回的默认值(如果不指定,则返回 NULL)。
-- PARTITION BY: 可选参数,用于将结果集划分为多个部分,LEAD 函数将在每个部分内独立工作。
-- ORDER BY: 必须指定,用于定义窗口内行的顺序。
题目来源
180. 连续出现的数字 - 力扣(高频 SQL 50 题(基础版))
题目
表:Logs
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| id | int |
| num | varchar |
+-------------+---------+
在 SQL 中,id 是该表的主键。
id 是一个自增列。
找出所有至少连续出现三次的数字。
返回的结果表中的数据可以按 任意顺序 排列。
结果格式如下面的例子所示:
示例 1:
输入:
Logs 表:
+----+-----+
| id | num |
+----+-----+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 1 |
| 6 | 2 |
| 7 | 2 |
+----+-----+
输出:
Result 表:
+-----------------+
| ConsecutiveNums |
+-----------------+
| 1 |
+-----------------+
解释:1 是唯一连续出现至少三次的数字。
解法一(lag + lag)
select
num,
-- num列向上偏移一行
lag(num,1) over (order by id) num1,
-- num列向上偏移两行
lag(num,2) over (order by id) num2
from
Logs
-- 输出
-- num、num1、num2三列数值相同,则代表一个数字连续出现三次
| num | num1 | num2 |
| --- | ---- | ---- |
| 1 | null | null |
| 1 | 1 | null |
| 1 | 1 | 1 |
| 2 | 1 | 1 |
| 1 | 2 | 1 |
| 2 | 1 | 2 |
| 2 | 2 | 1 |
select
num ConsecutiveNums
from
(select
num,
lag(num,1) over (order by id) num1,
lag(num,2) over (order by id) num2
from
Logs)t
where t.num = t.num1 AND t.num = t.num2
-- 输出
| ConsecutiveNums |
| --------------- |
| 1 |
解法二(lag + lead)
select
num,
-- num列向上偏移一行
lag(num,1) over (order by id) num1,
-- num列向下偏移一行
lead(num,1) over (order by id) num2
from
Logs
-- 输出
-- num、num1、num2三列数值相同,则代表一个数字连续出现三次
| num | num1 | num2 |
| --- | ---- | ---- |
| 1 | null | 1 |
| 1 | 1 | 1 |
| 1 | 1 | 2 |
| 2 | 1 | 1 |
| 1 | 2 | 2 |
| 2 | 1 | 2 |
| 2 | 2 | null |
select
num ConsecutiveNums
from
(select
num,
lag(num,1) over (order by id) num1,
lead(num,1) over (order by id) num2
from
Logs)t
where t.num = t.num1 AND t.num = t.num2
-- 输出
| ConsecutiveNums |
| --------------- |
| 1 |