LeetCode MySQL 刷题条记 (十)

129 阅读4分钟

「4月日新计划更文活动」

题目:182. 查找重复的电子邮箱

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| email       | varchar |
+-------------+---------+
id 是该表的主键列。
此表的每一行都包含一封电子邮件。电子邮件不包含大写字母。
 

需求

编写一个 SQL 查询来报告所有重复的电子邮件。 请注意,可以保证电子邮件字段不为 NULL。 以 **任意顺序 **返回结果表。

解析

# Write your MySQL query statement below

select distinct(a.email)   from person a  join person  b  on a.email = b.email and a.id !=b.id
# Write your MySQL query statement below

select email from ( select distinct(a.email)    from person a  right outer join person  b  on a.email = b.email and a.id !=b.id ) c where email is not null

题目:1050. 合作过至少三次的演员和导演

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| actor_id    | int     |
| director_id | int     |
| timestamp   | int     |
+-------------+---------+
timestamp 是这张表的主键.

需求

写一条SQL查询语句获取合作过至少三次的演员和导演的 id 对 (actor_id, director_id)

解析

# Write your MySQL query statement below

select  actor_id,director_id  from ActorDirector group by actor_id,director_id having count(*)>=3
# Write your MySQL query statement below

select  actor_id,director_id  from ActorDirector group by actor_id,director_id having count(actor_id )>=3
and count(director_id  )>=3

题目:1587. 银行账户概要 II

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| account      | int     |
| name         | varchar |
+--------------+---------+
account 是该表的主键.
表中的每一行包含银行里中每一个用户的账号.


+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| trans_id      | int     |
| account       | int     |
| amount        | int     |
| transacted_on | date    |
+---------------+---------+
trans_id 是该表主键.
该表的每一行包含了所有账户的交易改变情况.
如果用户收到了钱, 那么金额是正的; 如果用户转了钱, 那么金额是负的.
所有账户的起始余额为 0.

需求

写一个 SQL, 报告余额高于 10000 的所有用户的名字和余额. 账户的余额等于包含该账户的所有交易的总和. 返回结果表单没有顺序要求.

解析

# Write your MySQL query statement below

select  name, sum(amount) balance   from  Users  a right outer join Transactions b  on  a.account = b.account group  by a.account having balance > 10000

题目:1084. 销售分析III

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| product_id   | int     |
| product_name | varchar |
| unit_price   | int     |
+--------------+---------+
Product_id是该表的主键。
该表的每一行显示每个产品的名称和价格。

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| seller_id   | int     |
| product_id  | int     |
| buyer_id    | int     |
| sale_date   | date    |
| quantity    | int     |
| price       | int     |
+------ ------+---------+
这个表没有主键,它可以有重复的行。
product_id 是 Product 表的外键。
该表的每一行包含关于一个销售的一些信息。

需求

编写一个SQL查询,报告2019年春季才售出的产品。即2019-01-012019-03-31(含)之间出售的商品。

解析

# Write your MySQL query statement below

select p.product_id ,p.product_name  from Product p  right outer join Sales  s on p.product_id =s.product_id   
group by  p.product_id  having min(s.sale_date) >='2019-01-01' and max(s.sale_date) <='2019-03-31'

知识点

join 函数

  • 定义:JOIN 也被称为 INNER JOIN,属于内连接,也称为等值连接,是JOIN操作的最常用形式之一。它返回两个表中存在匹配条件的行。JOIN 仅返回左右两个表相匹配的行,不会包括没有匹配的行
  • 语句格式:栗子🌰182 select list from person a join person b on a.email = b.email or SELECT Orders.OrderID, Customers.CustomerName FROM Orders INNER JOIN Customers ON Orders.CustomerID = Customers.CustomerID

having 函数

  • 定义:HAVING是MySQL中一个用于在GROUP BY查询中过滤结果的关键字。
  • 组合使用:可以让你在查询中使用聚集函数(如COUNT、SUM、AVG等),并按照指定的条件对其进行过滤,从而得到满足特定条件的结果
  • 语句格式: select 列名1 , count(*) as 新列名 from 表 order by 列名 having 过滤条件;
  • 注意⚠️:唯一的差别是WHERE过滤行,而HAVING过滤分组 - WHERE在数据分组前进行过滤 - HAVING在数据分组后进行过滤(having 过滤数据为已经过滤后的数据在进行二遍过滤)

left join vs right join vs inner join 函数区别

  • INNER JOIN:INNER JOIN操作将只返回两个表都包含的行。在这种情况下,如果一个表中没有匹配的行,那么与之相关联的表中的数据将被忽略。
  • LEFT JOIN:LEFT JOIN操作将返回左表的所有行,以及与之相关联的右表中的匹配行。如果右表中没有匹配行,则返回NULL值。
  • RIGHT JOIN:RIGHT JOIN操作与LEFT JOIN相反。它将返回右表的所有行,以及与之相关联的左表中的匹配行。如果左表中没有匹配行,则返回NULL值。
  • 区别:LEFT JOIN和RIGHT JOIN的区别在于它们返回的结果集的不同