【SQL题解】力扣高频 SQL 50题|DAY2+3

SQL刷题记录

后天就考数据库概论了,今天继续练练力扣上的sql题目

以下皆出自力扣高频SQL50题

文章目录

25.12.21+22

2356

2356. 每位教师所教授的科目种类的数量

求每位老师教授科目种类数量

  • 先按照老师分组group by teacher_id
  • 再对count函数内的subject_id去重

DISTINCT 的作用:在聚合函数内部,只考虑唯一值(去重)

sql 复制代码
select teacher_id,count(distinct subject_id) as cnt from teacher group by teacher_id;

1045

1045. 买下所有产品的客户

sql 复制代码
# 错误写法
select customer_id 
from Customer c,Product p 
group by c.customer_id
having count(c.product_key) = count(p.product_key);

FROM Customer c, Product p

→ 这是 隐式 CROSS JOIN(笛卡尔积),会把每个客户和每个产品都配对一次,运行没错但是结果出错

正确写法:

sql 复制代码
# Write your MySQL query statement below
select customer_id 
from Customer
group by customer_id
having count(product_key) = (select count(*) from Product);
  • COUNT(distinct product_key):客户买了多少不同的产品,记得要去重
  • (SELECT COUNT(*) FROM Product):总共有多少产品

1731

1731. 每位经理的下属员工数量

sql 复制代码
select e.employee_id, 
e.name, 
count(r.reports_to) as reports_count,
round(avg(r.age),0) as average_age
from Employees e
join Employees r
on e.employee_id = r.reports_to
group by  r.reports_to
order by employee_id;

自连接

1978

1978. 上级经理已离职的公司员工

sql 复制代码
select
    employee_id
from
    Employees
where
    salary<30000
and
    manager_id is not null
and
    manager_id not in(select employee_id from Employees)
order by
    employee_id;

180

180. 连续出现的数字

找出所有至少连续出现三次的数字

核心:

连续出现的意味着相同数字的 Id 是连着的,由于这题问的是至少连续出现 3 次

  • 前三个的id是连续的,即

    sql 复制代码
    l1.id = l2.id -1 
    and l2.id = l3.id - 1 
  • 且前三个的num都一样

    sql 复制代码
    l1.num = l2.num 
    and l2.num = l3.num

所以:

sql 复制代码
select distinct l1.num as ConsecutiveNums
from Logs l1,Logs l2,Logs l3 
where
l1.id = l2.id -1 
and l2.id = l3.id - 1 
and l1.num = l2.num 
and l2.num = l3.num;

别忘了要去重

1667

1667. 修复表中的名字

  1. 分别截取首字母和剩余的字母
  2. 用upper函数把首字母转换成大写,用lower函数把剩余字母转换为小写
  3. 最后把两部分拼接起来
sql 复制代码
select user_id,
concat(upper(left(name,1)),lower(substring(name,2))) 
as name 
from Users 
order by user_id; 

left也可换为substring(name,1,1)

MySQL常用的字符串操作函数

、大小写转换

函数 说明 示例
UPPER(str)UCASE(str) 转大写 UPPER('hello') → 'HELLO'
LOWER(str)LCASE(str) 转小写 LOWER('WORLD') → 'world'

常用于统一格式、不区分大小写比较。

、去除空格

函数 说明 示例
TRIM(str) 去除首尾空格 TRIM(' abc ') → 'abc'
LTRIM(str) 去除左侧空格 LTRIM(' abc') → 'abc'
RTRIM(str) 去除右侧空格 RTRIM('abc ') → 'abc'
`TRIM([LEADING TRAILING BOTH] 'x' FROM str)`

、截取子串

函数 说明 示例
SUBSTRING(str, pos, len) 从位置 pos(从1开始)截取 len 个字符 SUBSTRING('abcdef', 2, 3) → 'bcd'
SUBSTR(str, pos, len) SUBSTRING(别名) SUBSTR('hello', 1, 2) → 'he'
LEFT(str, len) 取左边 len 个字符 LEFT('hello', 2) → 'he'
RIGHT(str, len) 取右边 len 个字符 RIGHT('hello', 2) → 'lo'

⚠️ 若 pos 为负数,SUBSTRING 从末尾开始(如 SUBSTRING('abc', -2, 1) → 'b')。

、查找位置

函数 说明 示例
LOCATE(substr, str [, start]) 返回子串首次出现位置(从1开始),可指定起始位置 LOCATE('o', 'hello') → 5 LOCATE('l', 'hello', 4) → 4
INSTR(str, substr) LOCATE,但参数顺序相反 INSTR('hello', 'l') → 3
POSITION(substr IN str) SQL 标准写法(MySQL 支持) POSITION('ll' IN 'hello') → 3

未找到返回 0(不是 NULL)。

、拼接字符串

函数 说明 示例
CONCAT(str1, str2, ...) 拼接多个字符串 CONCAT('a', 'b', 'c') → 'abc'
CONCAT_WS(separator, str1, str2, ...) 用分隔符拼接(自动跳过 NULL) CONCAT_WS(',', 'a', NULL, 'c') → 'a,c'

CONCAT() 中任意参数为 NULL,结果为 NULLCONCAT_WS 会忽略 NULL

、替换与填充

函数 说明 示例
REPLACE(str, from_str, to_str) 替换所有匹配子串 REPLACE('abcab', 'ab', 'X') → 'XcX'
LPAD(str, len, padstr) 左填充至 len 长度 LPAD('5', 3, '0') → '005'
RPAD(str, len, padstr) 右填充至 len 长度 RPAD('hi', 5, '*') → 'hi***'

、长度与重复

函数 说明 示例
LENGTH(str) 返回字节数(注意:中文占多字节) LENGTH('你好') → 6(UTF8)
CHAR_LENGTH(str) 返回字符数 CHAR_LENGTH('你好') → 2
REPEAT(str, count) 重复字符串 count REPEAT('ha', 3) → 'hahaha'

处理中文时,优先用 CHAR_LENGTH() 获取字符个数。

、其他实用函数

函数 说明 示例
REVERSE(str) 反转字符串 REVERSE('abc') → 'cba'
INSERT(str, pos, len, newstr) pos 开始替换 len 个字符为 newstr INSERT('abcdef', 2, 3, 'XX') → 'aXXef'
ELT(N, str1, str2, ...) 返回第 N 个字符串(类似 switch) ELT(2, 'a', 'b', 'c') → 'b'
FIELD(str, str1, str2, ...) 返回 str 在列表中的位置 FIELD('b', 'a', 'b', 'c') → 2

626

626. 换座位

  1. 先用count求座位总数

  2. 若座位 id 是奇数的学生,修改其 id 为 id+1;如果最后一个座位 id 也是奇数,则最后一个座位 id 不修改;若座位 id 是偶数的学生,修改其 id 为 id-1

  3. 用case实现该功能

    case的格式:

    sql 复制代码
    CASE WHEN[val1]THEN[res1]...ELSE[default]END
    -- 如果val1为true,返回res1,...否则返回default
  4. 最后用order by排序

sql 复制代码
# Write your MySQL query statement below
select 
    (case
        when id%2 != 0 and counts != id then id + 1
        when id%2 != 0 and counts = id then id
        else id - 1
    end) as id,
    student
from seat,(select count(*) as counts from seat) as seatCount
order by id;

记得给(select count(*) as counts from seat)起别名

因为每个派生表(子查询作为 FROM 的数据源)必须有一个别名(alias)

再优化一下

sql 复制代码
SELECT
    CASE
        WHEN id % 2 = 1 AND id != (SELECT MAX(id) FROM Seat) THEN id + 1
        WHEN id % 2 = 0 THEN id - 1
        ELSE id
    END AS id,
    student
FROM Seat
ORDER BY id;

用max(id)直接得出id的数量


(最后刷几道简单题吧)

595

595. 大的国家

简单题,或者or相连

sql 复制代码
select name,population,area
from world 
where area >= 3000000 or population >= 25000000;

1148

1148. 文章浏览 I

排序用order by

sql 复制代码
select distinct author_id as id
from views
where author_id = viewer_id
order by id;

1683

1683. 无效的推文

MySQL中计算字符串字符个数的函数

函数 含义 返回值 适用场景
CHAR_LENGTH(str) 字符个数 字符数量(按"字符"计) 通用、安全,尤其含中文、emoji 等多字节字符时
LENGTH(str) 字节数 字节长度(按"字节"计) 仅当字符串全是单字节字符(如纯英文、数字、ASCII 符号)时 ≈ 字符数
sql 复制代码
select 
    tweet_id
from 
    tweets
where 
    CHAR_LENGTH(content) > 15
相关推荐
李广坤2 小时前
Rust所有权、枚举和模式匹配
后端
l1t2 小时前
DeepSeek对Oracle 数据库新特性 SQL 宏的总结
数据库·人工智能·sql·oracle
酸菜谭丶2 小时前
SpringBoot工程如何发布第三方Jar
spring boot·后端·jar
是垚不是土2 小时前
MySQL8.0数据库GTID主从同步方案
android·网络·数据库·安全·adb
cnxy1882 小时前
MySQL地理空间数据完整使用指南
android·数据库·mysql
鲸说MySQL2 小时前
【MySQL事务(一)事务的操作流程】
数据库·mysql
程序边界2 小时前
10年Oracle运维转战国产数据库:迁移路上的“坑”与“光”
运维·数据库·oracle
bybitq2 小时前
深入浅出 Go 流程控制:从循环到延迟执行
开发语言·后端·golang
一个天蝎座 白勺 程序猿2 小时前
Apache IoTDB(12):深度解析时序数据聚合的GROUP BY与HAVING子句
数据库·sql·apache·iotdb