【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
相关推荐
Knight_AL3 分钟前
Spring 事务管理:为什么内部方法调用事务不生效以及如何解决
java·后端·spring
bcbnb8 分钟前
iOS代码混淆技术深度实践:从基础到高级全面解析
后端
加洛斯16 分钟前
SpringSecurity入门篇(2):替换登录页与config配置
前端·后端
用户83562907805121 分钟前
Python 实现 Excel 条件格式自动化
后端·python
源代码•宸38 分钟前
Golang语法进阶(协程池、反射)
开发语言·经验分享·后端·算法·golang·反射·协程池
Chan161 小时前
场景题:CPU 100% 问题怎么排查?
java·数据库·redis·后端·spring
电商API_180079052471 小时前
批量获取电商商品数据的主流技术方法全解析
大数据·数据库·人工智能·数据分析·网络爬虫
我是谁的程序员1 小时前
iOS 文件管理,在不越狱的前提下管理 iPhone / iPad 文件
后端
v***59831 小时前
springBoot连接远程Redis连接失败(已解决)
spring boot·redis·后端
rgeshfgreh2 小时前
Python流程控制:从条件到循环实战
前端·数据库·python