1667修复表中的名字

思路
-
字符串格式化:
- 使用
SUBSTRING(name, 1, 1)
获取用户名的第一个字符 - 通过
UPPER()
函数将第一个字符转换为大写 - 使用
SUBSTRING(name, 2)
获取用户名从第二个字符开始的子串 - 通过
LOWER()
函数将剩余字符转换为小写 - 最后用
CONCAT()
函数将处理后的两部分拼接起来,形成首字母大写、其余字母小写的标准化用户名
- 使用
-
结果排序:
- 按
user_id
升序排列结果,确保输出顺序的一致性
- 按
-
应用场景:
- 统一用户名的格式,解决可能存在的大小写混乱问题
- 例如,将 "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"),对应患者同时患有多种疾病,且目标疾病非首个记录的情况。
- 结果字段与用途
- 选取
patient_id
(患者 ID)、patient_name
(患者姓名)、conditions
(疾病情况)三个字段,完整呈现患者身份与患病信息。 - 未额外排序,直接返回符合条件的原始记录(若需固定顺序,可补充
ORDER BY patient_id
等排序语句)。
- 场景适用性
适用于医疗数据筛选,尤其是当conditions
字段用 "空格" 分隔多种疾病、且目标疾病编码以 "DIAB1" 开头(如糖尿病相关疾病编码)的场景,能避免漏筛或误筛(例如不会匹配 "ADIAB123" 这类不含目标疾病的记录)。
SQL语句
SELECT patient_id, patient_name, conditions
FROM Patients
WHERE conditions LIKE 'DIAB1%' OR conditions LIKE '% DIAB1%';
196删除重复的电子邮箱

思路
-
自连接表操作:
- 将 Person 表与自身连接,分别使用别名 p1 和 p2
- 连接条件是两个记录的邮箱相同(
p1.Email = p2.Email
)
-
删除重复记录的判定:
- 条件
p1.Id > p2.Id
表示:当两个记录邮箱相同时,保留 ID 较小的记录(p2),删除 ID 较大的重复记录(p1) - 这样就能确保每个邮箱只留下 ID 最小的那条记录
- 条件
-
删除语法说明:
- 使用
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 条,即为第二高薪资)。
- 处理 "无第二高薪资" 的情况
- 使用
IFNULL(..., NULL)
函数:若子查询未找到结果(例如表中只有 1 条薪资记录或无记录),则返回 NULL,避免查询结果显示 "无数据" 而非明确的 NULL 值。
- 结果命名
- 将最终结果列命名为
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指定连接符)。
- 结果排序
通过ORDER BY sell_date ASC将最终结果按销售日期升序排列,使数据按时间顺序呈现,便于查看销售趋势。
- 场景适用性
适用于销售数据汇总场景,例如电商或零售行业,需要快速了解 "每日卖了多少种商品" 以及 "具体卖了哪些商品",结果直观且信息完整。
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关联,确保能同时获取商品名称和对应的销售数据。
- 时间范围筛选
WHERE o.order_date BETWEEN '2020-02-01' AND '2020-02-29'限定只统计 2020 年 2 月(含 2 月 1 日至 2 月 29 日)的订单数据,聚焦特定月份的销售情况。
- 分组与聚合计算
GROUP BY p.product_name按商品名称分组,确保每个商品只生成一条汇总记录。
SUM(o.unit) as unit计算每个商品在 2 月的总销售量(unit为单条订单的商品数量),结果列名为unit。
- 销量阈值筛选
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');