【LeetCode: SQL专题 : SQL97 返回顾客名称和相关订单号以及每个订单的总和 + 联表查询】

在这里插入图片描述

🚀 算法题 🚀

🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀
🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨
🌲 作者简介:硕风和炜,优快云-Java领域优质创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享💎💎💎
🌲 恭喜你发现一枚宝藏博主,赶快收入囊中吧🌻
🌲 人生如棋,我愿为卒,行动虽慢,可谁曾见我后退一步?🎯🎯

🚀 算法题 🚀

在这里插入图片描述
在这里插入图片描述

🚩 题目链接

⛲ 题目描述

Customers 表有字段,顾客名称:cust_name、顾客id:cust_id
在这里插入图片描述
Orders订单信息表,含有字段,订单号:order_num、顾客id:cust_id
在这里插入图片描述
OrderItems表有字段,商品订单号:order_num、商品数量:quantity、商品价格:item_price
在这里插入图片描述
【问题】
除了返回顾客名称和订单号,返回 Customers 表中的顾客名称(cust_name)和Orders 表中的相关订单号(order_num),添加第三列 OrderTotal,其中包含每个订单的总价,并按顾客名称再按订单号对结果进行升序排序。

【示例结果】返回顾客名称 cust_name、订单号order_num、订单总额OrderTotal
在这里插入图片描述
【示例解析】
例如顾客名称cust_name为an的顾客的订单a5的订单总额为quantity*item_price = 15 * 25 = 375,最后以cust_name和order_num来进行升序排序。

🌟 求解思路&实现代码&运行结果


⚡ 联表查询

<think>嗯,用户想了解如何用SQL解决LeetCode上的编程算法问题。首先,我需要确定用户对SQLLeetCode的熟悉程度。可能他们正在准备面试,或者想提升数据库查询能力。LeetCode上的SQL题通常涉及数据查询、聚合、连接、窗口函数等,我得选几个经典例子来说明。 首先,考虑用户可能遇到的简单题,比如查找重复的电子邮箱。这个问题可以用GROUP BYHAVING子句解决,这能展示基本的聚合过滤。然后,可能需要中等难度的问题,比如第二高的薪水,这时候LIMITOFFSET或者子查询会派上用场。但要注意处理NULL的情况。 接下来,高级问题可能需要窗口函数,比如部门工资最高的员工。这里要使用RANK()或者MAX()配合PARTITION BY,同时需要多连接。这部分需要详细解释窗口函数的工作原理。 还有自连接的情况,比如连续出现的数字,可能需要比较相邻行的数据,这时候LAG函数或者自连接的方法都可以,但性能可能不同。另外,用户可能对如何处理复杂逻辑,如递归查询或层次结构的问题感兴趣,比如员工薪水的中位数,可能需要使用ROW_NUMBERCOUNT结合的方法。 需要注意,用户可能对不同的SQL方言(如MySQL vs PostgreSQL)的差异不太清楚,所以最好使用通用的语法,或者指出不同之处。同时,提醒他们注意测试边界情况,如空、重复值等。还要强调思路的重要性,比如先理解问题,再拆解步骤,最后组合成查询语句。 另外,用户可能希望了解优化技巧,比如索引的使用、避免不必要的子查询等,但LeetCode通常更关注正确性而非性能。不过,在复杂题目中,优化可能有助于通过更大的测试用例。 最后,总结一下常用的SQL知识点,并推荐练习题目,帮助他们循序渐进。确保示例正确,语法无误,并符合用户提到的格式要求,比如数学达式用$...$,独立公式用$$...$$,但在这里可能用不上太多数学公式,但如果有涉及计算的例子,如平均值、总和等,需要正确应用。</think>好的,我将以LeetCode典型题目为例,分步骤讲解如何用SQL解决编程算法问题。以下是关键知识点案例解析: --- ### 一、基础核心技巧 #### 1. 重复数据检测(LeetCode 182) **题目**:查找重复的电子邮箱 ```sql SELECT Email FROM Person GROUP BY Email HAVING COUNT(Email) > 1; ``` **关键点**: - `GROUP BY` 分组统计 - `HAVING` 过滤聚合结果(与`WHERE`的区别在于执行顺序) #### 2. 第N高记录(LeetCode 176) **题目**:查找第二高的薪水 ```sql SELECT MAX(salary) AS SecondHighestSalary FROM Employee WHERE salary < (SELECT MAX(salary) FROM Employee); ``` **优化方案**(避免嵌套查询): ```sql SELECT DISTINCT salary FROM Employee ORDER BY salary DESC LIMIT 1 OFFSET 1; ``` --- ### 二、中级进阶操作 #### 1. 多查询LeetCode 184) **题目**:部门工资最高的员工 ```sql SELECT d.name AS Department, e.name AS Employee, e.salary FROM Employee e JOIN Department d ON e.departmentId = d.id WHERE (e.departmentId, e.salary) IN ( SELECT departmentId, MAX(salary) FROM Employee GROUP BY departmentId ); ``` #### 2. 窗口函数应用(LeetCode 185) **题目**:部门工资前三高的所有员工 ```sql SELECT Department, Employee, Salary FROM ( SELECT d.name AS Department, e.name AS Employee, e.salary AS Salary, DENSE_RANK() OVER (PARTITION BY e.departmentId ORDER BY e.salary DESC) AS rnk FROM Employee e JOIN Department d ON e.departmentId = d.id ) tmp WHERE rnk <= 3; ``` --- ### 三、高级复杂场景 #### 1. 时间序列分析(LeetCode 180) **题目**:查找连续出现至少3次的数字 ```sql SELECT DISTINCT num AS ConsecutiveNums FROM ( SELECT num, LAG(num,1) OVER (ORDER BY id) AS prev1, LAG(num,2) OVER (ORDER BY id) AS prev2 FROM Logs ) tmp WHERE num = prev1 AND num = prev2; ``` #### 2. 递归查询LeetCode 569) **题目**:员工薪水中位数 ```sql SELECT Id, Company, Salary FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY Company ORDER BY Salary, Id) AS rk, COUNT(*) OVER (PARTITION BY Company) AS cnt FROM Employee ) t WHERE rk BETWEEN cnt/2.0 AND cnt/2.0 + 1; ``` --- ### 四、高频知识点总结 | 技能类型 | 典型语法/函数 | LeetCode例题 | |----------------|-------------------------------|--------------| | 聚合统计 | `GROUP BY`, `HAVING` | 182, 586 | | 多连接 | `JOIN`, `UNION` | 175, 184 | | 窗口函数 | `RANK()`, `ROW_NUMBER()`, `LEAD/LAG` | 185, 197 | | 递归查询 | `WITH RECURSIVE` | 1270, 569 | | 日期处理 | `DATE_ADD`, `DATEDIFF` | 197, 601 | --- ### 五、调试建议 1. 先分解复杂问题为多个子查询 2. 使用`WITH`语句构建临时提高可读性 3. 注意NULL值的处理(如`COALESCE()`函数) 4. 测试边界条件(空、单行数据、重复值) 练习路线建议:从简单聚合(595题) → 多连接(181题) → 窗口函数(185题) → 递归查询(1270题)逐步深入。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

硕风和炜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值