Solutions to SQL interview questions at major LeetCode manufacturers (1)

Hello everyone, my name is Ning Yi.

Recently, SQL topics will be updated every day in the group.

It also indirectly urged me to work harder——

Topic one:

182. Find duplicate email addresses (easy)

Write a SQL query to find all duplicate email addresses in the Person table.

Example:

+----+---------+
| Id | Emai    |
+----+---------+
|1 |  [email protected] |
| 2 | [email protected]  |
|3 | [email protected]  |
+----+---------+

Based on the above input, your query should return the following results:

+---------+
| Email   |
+---------+
| [email protected] |
+---------+

Problem-solving ideas:

You can first use a subquery and use the count aggregate function combined with group by to query the number of each mailbox. Then use the parent query to determine the records with a mailbox number greater than 1, which is the final result we want to get.

Step 1:
Use a subquery to find out the number of each mailbox.

SELECT Email FROM(
  SELECT Email, COUNT(Email) AS num
  FROM Person
  GROUP BY Email

Step 2:
Based on the results obtained in the first step, we determine the records whose mailbox number num is greater than 1.

SELECT Email FROM(
  SELECT Email, COUNT(Email) AS num
  FROM Person
  GROUP BY Email
) AS a
WHERE num > 1;

If you want to test locally on your own computer, you can use this to quickly create a database statement:

-- 创建数据库
CREATE database SQLCode;
-- 选择数据库
USE SQLCode;


-- 创建科目表Person 
CREATE TABLE Person(
Id INT,
Email VARCHAR(10));
-- 插入语句
INSERT INTO Person VALUES
(1,'[email protected]'),
(2,'[email protected]'),
(3,'[email protected]');

Topic 2:

176. Second highest salary (easy)

Write a SQL query to obtain and return the second highest salary in the Employee table. If the second highest salary does not exist, the query should return null.

Example 1:

Input: Employee table

+----+--------+
| id | salary |
+----+--------+
|  1 | 100    |
|  2 | 200    |
|  3 | 300    |
+----+--------+

Output:

+---------------------+
| SecondHighestSalary |
+---------------------+
| 200                 |
+---------------------+

Example 2:

Input: Employee table:

+----+--------+
| id | salary |
+----+--------+
| 1  | 100    |
+----+--------+

Output:

+---------------------+
| SecondHighestSalary |
+---------------------+
| null                |
+---------------------+

Problem-solving ideas:

Sort the different salaries in descending order and then use LIMIT OFFSET to get the second highest salary.

However, if there are less than 2 pieces of different salary data in the table, it will be empty, so add an IFNULL for judgment.

Knowledge points:

(1) Basic usage of LIMIT clause:

Used to limit the number of records returned.

You can use LIMIT m,n to skip the first m records in the result set and take n records. This sentence is a bit confusing, let’s give an example.

Take the 7th to 9th records, that is, skip the first 6 records, start from the 7th record, and take the 3 records 7, 8, and 9. That should be achieved using LIMIT 6,3.

(2) Basic syntax of IFNULL statement:

IFNULL(value1,value2)

If value 1 is NULL, return value 2; if value 1 is not NULL, return value 1.

first step:

Sort the salaries in reverse order, use DISTINCT to remove duplicates, and use LIMIT 1,1 to get the second highest salary.

SELECT DISTINCT Salary
FROM Employee
ORDER by Salary DESC
LIMIT 1,1 # 获取第二高的salary

Step two:

If there is no second highest salary, return null, use IFNULL to achieve this.

SELECT IFNULL(
    (
        SELECT DISTINCT Salary
        FROM Employee
        ORDER by Salary DESC
        LIMIT 1,1 # 获取第二高的salary
    ),
    NULL # 如果没有,则为 NULL
)

If you want to test locally on your own computer, you can use this to quickly create a data table statement:

-- 创建员工表Employee 
CREATE TABLE Employee(
Id INT,
salary INT);
-- 插入语句
INSERT INTO Employee VALUES
(1,100),
(2,200),
(3,300);

Topic three:

180. Consecutive numbers (medium)

Table: Logs

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
|  id         | int     |
| num         | varchar |
+-------------+---------+

id is the primary key of this table.

Write a SQL query to find all numbers that occur at least three times in a row.

The data in the returned results table can be arranged in any order.

Example 1:

Input: Logs table

+----+-----+
| Id | Num |
+----+-----+
| 1  | 1   |
| 2  | 1   |
| 3  | 1   |
| 4  | 3   |
| 5  | 2   |
| 6  | 2   |
| 7  | 2   |
+----+-----+

Output:

+-----------------+
| ConsecutiveNums |
+-----------------+
| 1               |
| 2               |
+-----------------+

Problem-solving ideas:

Find the number that appears next time by using id+1, and find the number that appears next time by using id+2. Mainly, the number that appears next time and the next time is the same as the current number, which means it appears at least 3 times. conditions of.

Knowledge point: JOIN connection

Joint querying of multiple data tables requires the use of JOIN connections. There are several types of JOIN connections. In this question, we used inner joins.

INNER JOIN: Inner connection, you can also just write JOIN. Only data that matches the connection criteria will be retained in the two tables being joined, which is equivalent to the intersection of the two tables. If you join the same table before and after, it is also called a self-join.

first step:

Put the number that appears next time and the number that appears next time in the same table to facilitate comparison in the second step.

SELECT *
FROM Logs t1
JOIN Logs t2
ON t1.id+1=t2.id
JOIN Logs t3
ON t1.id+2=t3.id

Step two:

With the filter conditions added, the numbers in table t1 are equal to the numbers in table t2 and the numbers in table t3.

SELECT *
FROM Logs t1
JOIN Logs t2
ON t1.id+1=t2.id
JOIN Logs t3
ON t1.id+2=t3.id
WHERE t1.Num=t2. Num
    AND t1.Num=t3.Num;

third step:

Modify the fields after SELECT and only output NUM.

SELECT DISTINCT t1.Num
FROM Logs t1
JOIN Logs t2
ON t1.id+1=t2.id
JOIN Logs t3
ON t1.id+2=t3.id
WHERE t1.Num=t2. Num
    AND t1.Num=t3.Num;

If you want to test locally on your own computer, you can use this to quickly create a data table statement:

-- 创建表
CREATE TABLE Logs(
Id INT,
Num INT);
-- 插入语句
INSERT INTO Logs VALUES
(1,1),
(2,1),
(3,1),
(4,3),
(5,2),
(6,2),
(7,2);

Topic four:

1454. Active users (medium)

Now we have the Accounts table: this table contains the account id and the user name of the account.

Logins table: Contains the account id and login date of the logged in user, login_date. (Users may log in multiple times a day)

Write a SQL query to find the id and name of active users. Active users are those who have logged in to their account for at least 3 consecutive days. The returned result table is sorted by id.

The result table format is as shown in the following example:

Accounts table:

+----+----------+
| id | name     |
+----+----------+
| 1  | '小王'    |
| 7  | ‘小李'    |
+----+----------+

Logins table:

+----+------------+
| id | login_date |
+----+------------+
| 7  | 2020-05-30 |
| 1  | 2020-05-30 |
| 7  | 2020-05-31 |
| 7  | 2020-06-01 |
| 7  | 2020-06-03 |
| 1  | 2020-06-07 |
+----+------------+

User Xiao Wang with id = 1 has only logged in twice, so Xiao Wang is not an active user.

The user with id = 7, Xiao Li, has logged in for 3 consecutive days, so Xiao Li is an active user.

Problem-solving ideas:

This is also a continuous problem. It is the same as the idea of ​​finding continuous numbers above. Use a self-join to first connect the Accounts table and the Logins table.

Connect the Logins table again, name the alias L2, and only connect the dates in the L1 table that have the same ID and are within 2 days apart. In this way, all dates that differ by two days from the L1 table will be displayed.

For example: the L1 table is May 30th, and the L2 table will find dates of May 30th, May 31st, and June 1st at most. If corresponds to 3 dates, it means that the user has logged in for 3 consecutive days. If there are two dates corresponding to each other, it means that the user only logged in for two days within three days.

Knowledge points:

DATEDIFF calculates the number of days between two dates:

SELECT
  DATEDIFF('2022-04-11','2021-04-11') AS "间隔天数",
  DATEDIFF('2022-04-11 01:00','2022-04-10 23:00') AS "间隔天数"

first step:

First connect the tables and find the dates in the L1 and L2 tables that have the same ID and are within 2 days apart.

SELECT A.*,L1.login_date,L2.login_date
FROM Accounts A
JOIN logins L1 ON A.id = L1.id
JOIN Logins L2 ON L1.id=L2.id
    AND DATEDIFF(L2.login_date,L1.login_date) BETWEEN 0 AND 2

Step two:

Group the results found above and see how the same dates in the L1 table correspond to the number of dates in the L2 table.

SELECT A.*,L1.login_date
FROM Accounts A
JOIN logins L1 ON A.id = L1.id
JOIN Logins L2 ON L1.id=L2.id
    AND DATEDIFF(L2.login_date,L1.login_date) BETWEEN 0 AND 2
GROUP BY A.id,A.name,L1.login_date

third step:

The account number corresponding to the 3 records in the table above is what we are looking for. Then remove the fields after SELECT, leaving only the Account field.

SELECT A.*
FROM Accounts A
JOIN logins L1 ON A.id = L1.id
JOIN Logins L2 ON L1.id=L2.id
    AND DATEDIFF(L2.login_date,L1.login_date) BETWEEN 0 AND 2
GROUP BY A.id,A.name,L1.login_date
HAVING COUNT(DISTINCT L2.login_date)=3

If you want to test locally on your own computer, you can use this to quickly create a data table statement:

-- 创建表
CREATE TABLE Accounts(
Id INT,
name VARCHAR(10));
-- 插入语句
INSERT INTO Accounts VALUES
(1,'小王' ),
(7, '小李');
-- 创建表
CREATE TABLE Logins(
Id INT,
login_date DATETIME);
-- 插入语句
INSERT INTO Logins VALUES
(7,'2020-05-30' ),
(1,'2020-05-30' ),
(7,'2020-05-31' ),
(7,'2020-06-01' ),
(7,'2020-06-03' ),
(1,'2020-06-07' );

Click to follow and get started with programming without getting lost~

Guess you like

Origin blog.csdn.net/shine_a/article/details/127201711