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');

相关推荐
TTGGGFF2 小时前
云端服务器使用指南:利用Python操作mysql数据库
服务器·数据库·python
编程充电站pro3 小时前
SQL 性能优化:为什么少用函数在 WHERE 条件中?
数据库·sql
无敌最俊朗@3 小时前
通过Ubuntu和i.MX 6ULL开发板实现网络共享
服务器·数据库·ubuntu
TDengine (老段)3 小时前
TDengine 时序函数 DERIVATIVE 用户手册
大数据·数据库·sql·物联网·时序数据库·iot·tdengine
TDengine (老段)3 小时前
TDengine 时序函数 STATEDURATION 用户手册
大数据·数据库·sql·物联网·时序数据库·iot·tdengine
凯子坚持 c4 小时前
2025年大模型服务性能深度解析:从清华评测报告看蓝耘元生代MaaS平台的综合实力
大数据·数据库·人工智能
长安城没有风4 小时前
从入门到精通【Redis】理解Redis事务
数据库·redis·缓存
小园子的小菜4 小时前
MySQL 查询与更新语句执行过程深度解析:从原理到实践
数据库·mysql
老华带你飞4 小时前
学生信息管理系统|基于Springboot的学生信息管理系统设计与实现(源码+数据库+文档)
java·数据库·spring boot·后端·论文·毕设·学生信息管理系统