当前位置: 首页 > ai >正文

SQL练习(12/81)

目录

1.找类别最高值

使用子查询

使用窗口函数(MySQL8.X支持)

扩展:查找类别前N高的值

2.删除重复值并保留最小序号

delete实现

筛选无重复且序号最小值

select——where in

select——join&子查询

3.找带条件的连续值

窗口函数实现

日期比较函数


1.找类别最高值

184. 部门工资最高的员工 - 力扣(LeetCode)

错误的查询方式:

(看看都会写写全错版T^T)

SELECT department.name AS Department, employee.name AS Employee, employee.salary AS Salary
FROM employee
JOIN department ON employee.departmentId = department.id 
GROUP BY department.id 
HAVING MAX(salary);

问题分析

  1. GROUP BYSELECT 列不一致

    SELECT 中选择了 department.nameemployee.nameemployee.salary,但在 GROUP BY 中只按 department.id 分组。这会导致语法错误,因为 GROUP BY 后的列必须与 SELECT 中的非聚合列一致。
  2. HAVING 子句的使用

    HAVING MAX(salary) 是不合法的,因为 HAVING 子句需要一个条件来过滤分组结果。没有提供一个具体的条件,只是写了 MAX(salary)
  3. 逻辑问题

    目标是筛选每个部门的最高工资员工,但当前的查询逻辑无法实现这一点。需要先找到每个部门的最高工资,然后再关联员工表来获取对应的员工信息。

正确的查询方式:

使用子查询

select department.name as Department,employee.name as Employee,employee.salary as Salary
from employee
join department on employee.departmentId = department.id 
where (employee.salary,employee.departmentId) in(select max(salary),departmentIdfrom employeegroup by departmentId
)
  • 子查询 SELECT departmentId, MAX(salary) FROM Employee GROUP BY departmentId 找到每个部门的最高工资。

  • 外层查询通过 WHERE (departmentId, salary) IN (...) 筛选出这些最高工资对应的员工。

使用窗口函数(MySQL8.X支持)

SELECT Department, Employee, Salary
FROM (SELECT d.name AS Department, e.name AS Employee, e.salary AS Salary,RANK() OVER (PARTITION BY d.id ORDER BY e.salary DESC) AS rankFROM Employee eJOIN Department d ON e.departmentId = d.id
) AS ranked_employees
WHERE rank = 1;
  • 使用窗口函数 RANK(),对每个部门的员工按工资降序排名。

      PARTITION BY employee.departmentId:按 departmentId 分组

      ORDER BY employee.salary DESC:按工资降序排列,工资最高的员工排名为1。

  • 外层查询筛选出排名为1的员工,即每个部门的最高工资员工。

扩展:查找类别前N高的值

185. 部门工资前三高的所有员工 - 力扣(LeetCode)

使用方法2窗口函数进行推广

/* Write your T-SQL query statement below */
SELECT Department, Employee, Salary
FROM (SELECT d.name AS Department, e.name AS Employee, e.salary AS Salary,dense_RANK() OVER (PARTITION BY d.id ORDER BY e.salary DESC) AS rankFROM Employee eJOIN Department d ON e.departmentId = d.id
) AS ranked_employees
WHERE rank <= 3;

 

2.删除重复值并保留最小序号

196. 删除重复的电子邮箱 - 力扣(LeetCode)

delete实现

-- 用自连接:
delete p1
from person p1
join person p2 on p1.email=p2.email and p1.id>p2.id-- 不用自连接
DELETE p1 FROM Person p1,Person p2
WHEREp1.Email = p2.Email AND p1.Id > p2.Id

筛选无重复且序号最小值

select——where in

SELECT id, email
FROM person
WHERE (email, id) IN (SELECT email, MIN(id)FROM personGROUP BY email
);
  • 子查询SELECT email, MIN(id) FROM Person GROUP BY email 找到每个 email 的最小 id。这个子查询的结果是一个临时表,包含每个 email 和对应的最小 id

  • 主查询:通过 WHERE (email, id) IN (...) 筛选出 Person 表中那些 emailid 匹配子查询结果的记录。

select——join&子查询

SELECT p1.id, p1.email
FROM person p1
JOIN (SELECT email, MIN(id) AS min_idFROM personGROUP BY email
) p2 ON p1.email = p2.email AND p1.id = p2.min_id;
  • 子查询:  SELECT email, MIN(id) AS min_id FROM person GROUP BY email 找到每个 email 的最小 id。这个子查询的结果是一个临时表 p2,包含每个 email 和对应的最小 id

  • 主查询:通过 JOINperson 表和子查询的结果 p2 连接起来,条件是 p1.email = p2.email AND p1.id = p2.min_id,这样可以筛选出每个 email 的最小 id 对应的记录。

(select力扣上运行不了但我觉得逻辑上是这样)

3.找带条件的连续值

197. 上升的温度 - 力扣(LeetCode)

窗口函数实现

# Write your MySQL query statement below
select id as Id from (select id,temperature,recordDate,LAG(temperature,1) over (order by recordDate) as pre_temperature,LAG(recordDate,1) over (order by recordDate) as pre_recordDatefrom weather
) as queryweather
where pre_temperature<temperature and DATEDIFF(recordDate,pre_recordDate)=1
  • 子查询LAG(temperature, 1) OVER (ORDER BY recordDate) AS pre_temperature:获取前一天的温度。LAG(recordDate, 1) OVER (ORDER BY recordDate) AS pre_recordDate:获取前一天的日期。

  • 主查询WHERE pre_temperature < temperature:确保当前温度高于前一天的温度。

                   AND DATEDIFF(recordDate, pre_recordDate) = 1:确保当前日期和前一天的日期是连续的。

日期比较函数

  • DATEDIFF():计算两个日期之间的天数差

    SELECT DATEDIFF('2025-05-18', '2025-05-10') AS days_difference;
  • DATE_ADD()DATE_SUB():在日期上加上或减去指定的时间间隔

    SELECT DATE_ADD('2025-05-18', INTERVAL 10 DAY) AS future_date;
    SELECT DATE_SUB('2025-05-18', INTERVAL 10 DAY) AS past_date;


后面两题都用到了之前遇到过的知识点,就不过多赘述啦

(其实是靠自己写出来了 嘿嘿,虽然他们都是简单的题)


4.

586. 订单最多的客户 - 力扣(LeetCode)

select customer_number
from (select customer_number,count(*) as cn from ordersgroup by customer_numberorder by cn DESC
) as subquery
limit 1

 

5.

511. 游戏玩法分析 I - 力扣(LeetCode)

select player_id,event_date as first_login
from activity
where (player_id,event_date) in(select player_id,min(event_date)from activitygroup by player_id
)

http://www.xdnf.cn/news/7043.html

相关文章:

  • C++ map容器: 插入操作
  • 一次页面假死分析
  • SpringBoot3+AI
  • Text models —— BERT,RoBERTa, BERTweet,LLama
  • 项目制作流程
  • html文件cdn一键下载并替换
  • 第五部分:阶段项目 4:构建 RESTful API 服务器
  • 创建指定版本的vite项目
  • 《Python星球日记》 第88天:ChatGPT 与 LangChain
  • ADB基本操作和命令
  • 【机器学习】工具入门:飞牛启动Dify Ollama Deepseek
  • 开始学习做游戏,就现在
  • 短剧小程序系统开发源码上架,短剧项目市场分析
  • 【上位机——WPF】布局控件
  • vue3 elementplus tabs切换实现
  • Node.js 实战六:日志系统设计 —— 不只是 console.log,而是可追溯的行为记录链
  • Mac 在恢复模式下出现 旋转地球图标 但进度非常缓慢
  • 【android bluetooth 协议分析 01】【HCI 层介绍 3】【NUMBER_OF_COMPLETED_PACKETS 事件介绍】
  • 利用html制作简历网页和求职信息网页
  • Ubuntu 环境中 MATLAB 安装常见问题及解决方案
  • 【大模型系列】logprobs(对数概率)参数
  • boost变换器simulink仿真,开环,电压环控制,电流环控制,电压电流双闭环控制策略,含bode图
  • 从0开始学linux韦东山教程第四章问题小结(1)
  • React Native 0.68 安装react-native-picker报错:找不到compile
  • 整理了 2009 - 2025 年的【199 管综真题 + 解析】PDF,全套共 34 份文件
  • pycharm连接github(详细步骤)
  • 2025年- H28-Lc136- 24.两两交换链表中的节点(链表)---java版
  • 在超频单片机时,需要注意哪些稳定性问题?
  • 英语学习5.18
  • 深度估计中为什么需要已知相机基线(known camera baseline)?