LeetCode 高频SQL50(基础版)

文章目录

[高频 SQL 50 题(基础版)](https://leetcode.cn/studyplan/sql-free-50/)

1 查询

1757. 可回收且低脂的产品

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| product_id  | int     |
| low_fats    | enum    |
| recyclable  | enum    |
+-------------+---------+
product_id 是该表的主键(具有唯一值的列)。
low_fats 是枚举类型,取值为以下两种 ('Y', 'N'),其中 'Y' 表示该产品是低脂产品,'N' 表示不是低脂产品。
recyclable 是枚举类型,取值为以下两种 ('Y', 'N'),其中 'Y' 表示该产品可回收,而 'N' 表示不可回收。


select product_id from Products where low_fats="Y" and recyclable="Y";

584. 寻找用户推荐人

输入: 
Customer 表:
+----+------+------------+
| id | name | referee_id |
+----+------+------------+
| 1  | Will | null       |
| 2  | Jane | null       |
| 3  | Alex | 2          |
| 4  | Bill | null       |
| 5  | Zack | 1          |
| 6  | Mark | 2          |
+----+------+------------+
输出:
+------+
| name |
+------+
| Will |
| Jane |
| Bill |
| Zack |
+------+

select name from Customer 
where referee_id!=2 or referee_id is null;

MySQL 使用三值逻辑 —— TRUE, FALSE 和 UNKNOWN。任何与 NULL 值进行的比较都会与第三种值 UNKNOWN 做比较。这个“任何值”包括 NULL 本身!这就是为什么 MySQL 提供 IS NULL 和 IS NOT NULL 两种操作来对 NULL 特殊判断。

因此,在 WHERE 语句中我们需要做一个额外的条件判断 `referee_id IS NULL’。

595. 大的国家

World 表:

±------------±--------+

| Column Name | Type |

±------------±--------+

| name | varchar |

| continent | varchar |

| area | int |

| population | int |

| gdp | bigint |

±------------±--------+

name 是该表的主键(具有唯一值的列)。

这张表的每一行提供:国家名称、所属大陆、面积、人口和 GDP 值。

如果一个国家满足下述两个条件之一,则认为该国是 大国 :

面积至少为 300 万平方公里(即,3000000 km2),或者

人口至少为 2500 万(即 25000000)

编写解决方案找出 大国 的国家名称、人口和面积。

按 任意顺序 返回结果表。

select name,population,area from World
where area>=3000000 or population>=25000000;

1148. 文章浏览 I

<font style="color:rgba(38, 38, 38, 0.75);background-color:#FFFFFF;">Views</font> 表:

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| article_id    | int     |
| author_id     | int     |
| viewer_id     | int     |
| view_date     | date    |
+---------------+---------+
此表可能会存在重复行。(换句话说,在 SQL 中这个表没有主键)
此表的每一行都表示某人在某天浏览了某位作者的某篇文章。
请注意,同一人的 author_id 和 viewer_id 是相同的。

请查询出所有浏览过自己文章的作者

结果按照 <font style="color:rgba(38, 38, 38, 0.75);background-color:#FFFFFF;">id</font> 升序排列。

查询结果的格式如下所示:

示例 1:

输入:
Views 表:
+------------+-----------+-----------+------------+
| article_id | author_id | viewer_id | view_date  |
+------------+-----------+-----------+------------+
| 1          | 3         | 5         | 2019-08-01 |
| 1          | 3         | 6         | 2019-08-02 |
| 2          | 7         | 7         | 2019-08-01 |
| 2          | 7         | 6         | 2019-08-02 |
| 4          | 7         | 1         | 2019-07-22 |
| 3          | 4         | 4         | 2019-07-21 |
| 3          | 4         | 4         | 2019-07-21 |
+------------+-----------+-----------+------------+

输出:
+------+
| id   |
+------+
| 4    |
| 7    |
+------+

select 
    distinct author_id as id
from Views
where author_id=viewer_id
order by id

1683. 无效的推文

表:<font style="color:rgba(38, 38, 38, 0.75);background-color:rgb(240, 240, 240);">Tweets</font>

+----------------+---------+
| Column Name    | Type    |
+----------------+---------+
| tweet_id       | int     |
| content        | varchar |
+----------------+---------+
在 SQL 中,tweet_id 是这个表的主键。
这个表包含某社交媒体 App 中所有的推文。

查询所有无效推文的编号(ID)。当推文内容中的字符数严格大于 <font style="color:rgba(38, 38, 38, 0.75);background-color:#FFFFFF;">15</font> 时,该推文是无效的。

任意顺序返回结果表。

查询结果格式如下所示:

输入:
Tweets 表:
+----------+----------------------------------+
| tweet_id | content                          |
+----------+----------------------------------+
| 1        | Vote for Biden                   |
| 2        | Let us make America great again! |
+----------+----------------------------------+

输出:
+----------+
| tweet_id |
+----------+
| 2        |
+----------+
解释:
推文 1 的长度 length = 14。该推文是有效的。
推文 2 的长度 length = 32。该推文是无效的。

select tweet_id
from Tweets
where char_length(content)>15;

对于SQL表,用于计算字符串中字符数的最佳函数是 CHAR_LENGTH(str),它返回字符串 str 的长度。

另一个常用的函数 LENGTH(str) 在这个问题中也适用,因为列 content 只包含英文字符,没有特殊字符。否则,LENGTH() 可能会返回不同的结果,因为该函数返回字符串 str 的字节数,某些字符包含多于 1 个字节。

以字符 ‘¥’ 为例:CHAR_LENGTH() 返回结果为 1,而 LENGTH() 返回结果为 2,因为该字符串包含 2 个字节。

2 连接

1378. 使用唯一标识码替换员工ID

展示每位用户的 唯一标识码(unique ID );如果某位员工没有唯一标识码,使用 null 填充即可。

创建表并插入数据

首先,我们需要创建两个表 Employees 和 EmployeeUNI,并插入相应的数据。

-- 创建 Employees 表
CREATE TABLE Employees (
    id INT PRIMARY KEY,
    name VARCHAR(100)
);

-- 插入数据到 Employees 表
INSERT INTO Employees (id, name) VALUES
(1, 'Alice'),
(7, 'Bob'),
(11, 'Meir'),
(90, 'Winston'),
(3, 'Jonathan');

-- 创建 EmployeeUNI 表
CREATE TABLE EmployeeUNI (
    id INT,
    unique_id INT,
    PRIMARY KEY (id, unique_id)
);

-- 插入数据到 EmployeeUNI 表
INSERT INTO EmployeeUNI (id, unique_id) VALUES
(3, 1),
(11, 2),
(90, 3);

执行查询

接下来,我们使用 LEFT JOIN 将这两个表连接起来,以获取每个员工的唯一标识码。如果某个员工没有唯一标识码,则 unique_id 字段会显示为 NULL。

select 
    u.unique_id,
    e.name
from 
    Employees e
left join
    EmployeeUNI u on e.id = u.id;

LEFT JOIN 确保了 Employees 表中的所有记录都包含在结果中。

如果某个员工在 EmployeeUNI 表中没有对应的记录,那么 unique_id 字段将显示为 NULL。

1068. 产品销售分析 I

-- 创建 Sales 表
CREATE TABLE Sales (
    sale_id INT,
    product_id INT,
    year INT,
    quantity INT,
    price INT,
    PRIMARY KEY (sale_id, year)
);

-- 插入数据到 Sales 表
INSERT INTO Sales (sale_id, product_id, year, quantity, price) VALUES
(1, 100, 2008, 10, 5000),
(2, 100, 2009, 12, 5000),
(7, 200, 2011, 15, 9000);

-- 创建 Product 表
CREATE TABLE Product (
    product_id INT PRIMARY KEY,
    product_name VARCHAR(100)
);

-- 插入数据到 Product 表
INSERT INTO Product (product_id, product_name) VALUES
(100, 'Nokia'),
(200, 'Apple'),
(300, 'Samsung');
select
    p.product_name,s.year,s.price
from 
    Sales s
left join
    Product p 
on 
    s.product_id=p.product_id

INNER JOIN:我们将 Sales 表和 Product 表通过 product_id 字段进行连接。这样可以确保只有当 Sales 表中的 product_id 在 Product 表中存在时,才会返回相应的记录。

选择字段:我们选择了 Product 表中的 product_name 和 Sales 表中的 year 和 price 字段。

1581. 进店却未进行过交易的顾客

-- 创建 Visits 表
CREATE TABLE Visits (
    visit_id INT,
    customer_id INT,
    PRIMARY KEY (visit_id)
);

-- 插入数据到 Visits 表
INSERT INTO Visits (visit_id, customer_id) VALUES
(1, 23),
(2, 9),
(4, 30),
(5, 54),
(6, 96),
(7, 54),
(8, 54);

-- 创建 Transactions 表
CREATE TABLE Transactions (
    transaction_id INT,
    visit_id INT,
    amount INT,
    PRIMARY KEY (transaction_id)
);

-- 插入数据到 Transactions 表
INSERT INTO Transactions (transaction_id, visit_id, amount) VALUES
(2, 5, 310),
(3, 5, 300),
(9, 5, 200),
(12, 1, 910),
(13, 2, 970);
select 
    v.customer_id, 
    count(v.visit_id) as count_no_trans
from 
    Visits v 
left join
    Transactions t
on v.visit_id=t.visit_id
where 
    t.visit_id is null
group by
    v.customer_id;

LEFT JOIN:将 Visits 表和 Transactions 表通过 visit_id 字段进行左连接。这样可以确保所有 Visits 表中的记录都会出现在结果中,即使它们在 Transactions 表中没有对应的记录。

WHERE t.visit_id IS NULL:这个条件用于筛选出那些在 Transactions 表中没有对应记录的访问记录,即那些没有进行交易的访问。

GROUP BY v.customer_id:我们按 customer_id 分组,以便统计每个顾客的无交易访问次数。

COUNT(v.visit_id):计算每个顾客的无交易访问次数。

197. 上升的温度

找出那些温度比前一天高的日期,并返回这些日期对应的 <font style="color:rgb(44, 44, 54);">id</font>。我们可以使用自连接(self join)来比较每一天的温度与其前一天的温度。

-- 创建 Weather 表
CREATE TABLE Weather (
    id INT PRIMARY KEY,
    recordDate DATE,
    temperature INT
);

-- 插入数据到 Weather 表
INSERT INTO Weather (id, recordDate, temperature) VALUES
(1, '2015-01-01', 10),
(2, '2015-01-02', 25),
(3, '2015-01-03', 20),
(4, '2015-01-04', 30);
select w1.id
from 
    Weather w1
    join
        Weather w2 
    on w1.recordDate=date_add(w2.recordDate,interval 1 day)
where
    w1.temperature > w2.temperature
  • JOIN:我们将 <font style="color:rgb(44, 44, 54);background-color:#FAFAFA;">Weather</font> 表与自身进行连接,连接条件是 <font style="color:rgb(44, 44, 54);background-color:#FAFAFA;">w1.recordDate</font> 等于 <font style="color:rgb(44, 44, 54);background-color:#FAFAFA;">w2.recordDate</font> 的下一天(即 <font style="color:rgb(44, 44, 54);background-color:#FAFAFA;">w1.recordDate = DATE_ADD(w2.recordDate, INTERVAL 1 DAY)</font>)。这样可以确保我们在比较每一天的温度时,能够找到前一天的记录。
  • WHERE w1.temperature > w2.temperature:这个条件用于筛选出那些温度比前一天高的记录。
  • SELECT w1.id:我们只需要返回符合条件的记录的 <font style="color:rgb(44, 44, 54);background-color:#FAFAFA;">id</font>

1661. 每台机器的进程平均运行时间

  1. 计算每个进程的运行时间:对于每个进程,我们需要找到它的开始时间和结束时间,并计算它们之间的差值。
  2. 按机器分组:将计算出的运行时间按机器分组,计算每台机器的总运行时间和进程数量。
  3. 计算平均耗时:对于每台机器,计算总运行时间除以进程数量,并将结果四舍五入到三位小数。
-- 创建 Activity 表
CREATE TABLE Activity (
    machine_id INT,
    process_id INT,
    activity_type ENUM('start', 'end'),
    timestamp FLOAT,
    PRIMARY KEY (machine_id, process_id, activity_type)
);

-- 插入数据到 Activity 表
INSERT INTO Activity (machine_id, process_id, activity_type, timestamp) VALUES
(0, 0, 'start', 0.712),
(0, 0, 'end', 1.520),
(0, 1, 'start', 3.140),
(0, 1, 'end', 4.120),
(1,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值