SQL语句——高级字符串函数 / 正则表达式 / 子句

1667修复表中的名字

思路

  1. 字符串格式化

    • 使用 SUBSTRING(name, 1, 1) 获取用户名的第一个字符
    • 通过 UPPER() 函数将第一个字符转换为大写
    • 使用 SUBSTRING(name, 2) 获取用户名从第二个字符开始的子串
    • 通过 LOWER() 函数将剩余字符转换为小写
    • 最后用 CONCAT() 函数将处理后的两部分拼接起来,形成首字母大写、其余字母小写的标准化用户名
  2. 结果排序

    • user_id 升序排列结果,确保输出顺序的一致性
  3. 应用场景

    • 统一用户名的格式,解决可能存在的大小写混乱问题
    • 例如,将 "alice" 转换为 "Alice",将 "BOB" 转换为 "Bob",将 "jOhN" 转换为 "John"

这个查询适用于需要标准化姓名格式的场景,使输出的用户名更加规范和统一。

SQL语句

复制代码
SELECT user_id, CONCAT(UPPER(SUBSTRING(name, 1, 1)), LOWER(SUBSTRING(name, 2))) AS name
FROM Users
ORDER BY user_id;

1527患某种疾病的患者

思路

筛选核心条件

通过LIKE模糊匹配,精准定位包含目标疾病的记录,涵盖两种场景:

  • conditions LIKE 'DIAB1%':匹配 "DIAB1" 作为conditions字段开头的情况(如 "DIAB100""DIAB1ABC"),对应患者仅患此疾病或此疾病排在首位的情况。
  • conditions LIKE '% DIAB1%':匹配 "DIAB1" 前有空格的情况(如 "XYZ DIAB100""ABC DIAB1XYZ"),对应患者同时患有多种疾病,且目标疾病非首个记录的情况。
  1. 结果字段与用途
  • 选取patient_id(患者 ID)、patient_name(患者姓名)、conditions(疾病情况)三个字段,完整呈现患者身份与患病信息。
  • 未额外排序,直接返回符合条件的原始记录(若需固定顺序,可补充ORDER BY patient_id等排序语句)。
  1. 场景适用性

适用于医疗数据筛选,尤其是当conditions字段用 "空格" 分隔多种疾病、且目标疾病编码以 "DIAB1" 开头(如糖尿病相关疾病编码)的场景,能避免漏筛或误筛(例如不会匹配 "ADIAB123" 这类不含目标疾病的记录)。

SQL语句

复制代码
SELECT patient_id, patient_name, conditions
FROM Patients
WHERE conditions LIKE 'DIAB1%' OR conditions LIKE '% DIAB1%';

196删除重复的电子邮箱

思路

  1. 自连接表操作

    • 将 Person 表与自身连接,分别使用别名 p1 和 p2
    • 连接条件是两个记录的邮箱相同(p1.Email = p2.Email
  2. 删除重复记录的判定

    • 条件 p1.Id > p2.Id 表示:当两个记录邮箱相同时,保留 ID 较小的记录(p2),删除 ID 较大的重复记录(p1)
    • 这样就能确保每个邮箱只留下 ID 最小的那条记录
  3. 删除语法说明

    • 使用 DELETE p1 FROM ... 语法,明确指定要删除的是 p1 表中的记录
    • 这是 MySQL 中删除重复记录的经典写法,通过自连接找到重复项并保留其中一条

SQL语句

复制代码
DELETE p1 FROM Person p1,
    Person p2
WHERE
    p1.Email = p2.Email AND p1.Id > p2.Id

176第二高的薪水

思路

核心子查询:筛选第二高薪资

  • 去重处理 :使用DISTINCT salary确保薪资不重复,避免因多个员工同薪资导致 "第二高" 计算偏差(例如若最高薪资有 2 人,仍需正确找到次高薪资)。
  • 排序与定位 :先按salary DESC降序排列薪资,再通过LIMIT 1 OFFSET 1取排序后的第 2 条记录(OFFSET 1表示跳过第 1 条,即最高薪资,LIMIT 1取 1 条,即为第二高薪资)。
  1. 处理 "无第二高薪资" 的情况
  • 使用IFNULL(..., NULL)函数:若子查询未找到结果(例如表中只有 1 条薪资记录或无记录),则返回 NULL,避免查询结果显示 "无数据" 而非明确的 NULL 值。
  1. 结果命名
  • 将最终结果列命名为SecondHighestSalary,使输出更清晰易读。

SQL语句

复制代码
SELECT IFNULL(
    (SELECT DISTINCT salary
     FROM Employee
     ORDER BY salary DESC
     LIMIT 1 OFFSET 1),
    NULL
) AS SecondHighestSalary;

1484按日期分组销售的产品

思路

核心统计维度

按日期分组:通过GROUP BY sell_date将数据按销售日期聚合,确保每个日期只输出一条汇总记录。

统计销售商品数:COUNT(DISTINCT(product))计算每日销售的不重复商品数量(避免同一商品当日多次销售导致计数重复),结果命名为num_sold。

拼接商品列表:GROUP_CONCAT(DISTINCT product ORDER BY product SEPARATOR ',')将每日销售的不重复商品按字母顺序排序后,用英文逗号连接成字符串,结果命名为products(DISTINCT去重、ORDER BY保证顺序、SEPARATOR指定连接符)。

  1. 结果排序

通过ORDER BY sell_date ASC将最终结果按销售日期升序排列,使数据按时间顺序呈现,便于查看销售趋势。

  1. 场景适用性

适用于销售数据汇总场景,例如电商或零售行业,需要快速了解 "每日卖了多少种商品" 以及 "具体卖了哪些商品",结果直观且信息完整。

SQL语句

复制代码
SELECT 
    sell_date,
    COUNT(DISTINCT(product)) AS num_sold, 
    GROUP_CONCAT(DISTINCT product ORDER BY product SEPARATOR ',') AS products
FROM 
    Activities
GROUP BY 
    sell_date
ORDER BY 
    sell_date ASC

1327列出指定时间段下的所有的下单产品

思路

表连接与数据关联

通过JOIN将Products表(商品信息)和Orders表(订单信息)通过product_id关联,确保能同时获取商品名称和对应的销售数据。

  1. 时间范围筛选

WHERE o.order_date BETWEEN '2020-02-01' AND '2020-02-29'限定只统计 2020 年 2 月(含 2 月 1 日至 2 月 29 日)的订单数据,聚焦特定月份的销售情况。

  1. 分组与聚合计算

GROUP BY p.product_name按商品名称分组,确保每个商品只生成一条汇总记录。

SUM(o.unit) as unit计算每个商品在 2 月的总销售量(unit为单条订单的商品数量),结果列名为unit。

  1. 销量阈值筛选

HAVING SUM(o.unit) >= 100筛选出总销量达到或超过 100 的商品,仅保留符合业务阈值的记录。

SQL语句

复制代码
SELECT 
    p.product_name,
    SUM(o.unit) as unit
FROM 
    Products p
JOIN 
    Orders o ON p.product_id = o.product_id
WHERE 
    o.order_date BETWEEN '2020-02-01' AND '2020-02-29'
GROUP BY 
    p.product_name
HAVING 
    SUM(o.unit) >= 100;

1517查找拥有有效邮箱的用户

思路

核心筛选:正则表达式匹配

通过REGEXP_LIKE(mail, '^[a-zA-Z][a-zA-Z0-9._-]*@leetcode\\.com$', 'c')定义邮箱的合法格式,规则拆解如下:

^[a-zA-Z]:邮箱前缀的第一个字符必须是字母(大写或小写),确保前缀开头合法。

a-zA-Z0-9._-\]\*:前缀后续字符可包含字母、数字、.、_、-,\*表示这些字符可出现 0 次或多次(覆盖不同长度的前缀)。 @leetcode\\\\.com$:固定匹配@leetcode.com域名,\\\\.是转义后的.(正则中.需转义才能表示实际的点号),$确保邮箱结尾就是该域名(避免后缀多余字符)。 第三个参数'c':表示区分大小写(即A和a视为不同字符,若需不区分大小写可改为'i')。 2. 结果返回 SELECT \*返回符合格式的用户所有字段(如user_id、name、mail等),直接获取完整的合法用户信息。 3. 场景适用性 适用于需要严格校验leetcode.com域名邮箱的场景,例如: 筛选平台的官方注册用户(排除非该域名的无效邮箱)。 清理用户表中的非法邮箱数据(如前缀含特殊字符、域名错误的邮箱)。 例如,合法邮箱如test123@leetcode.com、User_Name-123@leetcode.com会被选中;非法邮箱如123test@leetcode.com(前缀以数字开头)、test@leetcode.com.cn(域名多余后缀)会被排除。 ### SQL语句 SELECT * FROM users WHERE REGEXP_LIKE(mail, '^[a-zA-Z][a-zA-Z0-9._-]*@leetcode\\.com$', 'c');

相关推荐
java1234_小锋2 分钟前
Redis的热Key问题如何解决?
数据库·redis·缓存
wang6021252186 分钟前
FastAPI框架为什么在启动时建表
数据库
男孩李8 分钟前
linux下如何执行postgres数据库的sql文件
数据库·sql·postgresql
zwjapple12 分钟前
MySQL SQL 面试核心考点与注意事项总结
数据库·sql·mysql
乐韵天城13 分钟前
SpringBoot中如何手动开启数据库事务
数据库·spring boot
05大叔19 分钟前
Spring Day02
数据库·sql·spring
默默前行的虫虫25 分钟前
nicegui中多次调用数据库操作总结
数据库·python
鸽鸽程序猿31 分钟前
【Redis】事务
数据库·redis·缓存
Knight_AL1 小时前
MySQL 分区表应用案例:优化数据管理与性能
数据库·mysql
老华带你飞1 小时前
考试管理系统|基于java+ vue考试管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端