Skip to content

Commit

Permalink
feat: update solutions to lc problems: No.0570,0620,1251,1280,1934 (d…
Browse files Browse the repository at this point in the history
…oocs#1834)

* No.0570.Managers with at Least 5 Direct Reports
* No.0620.Not Boring Movies
* No.1251.Average Selling Price
* No.1280.Students and Examinations
* No.1934.Confirmation Rate
  • Loading branch information
yanglbme authored Oct 18, 2023
1 parent c306004 commit 49ee3ff
Show file tree
Hide file tree
Showing 15 changed files with 105 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,41 +59,26 @@ Employee 表:

<!-- 这里可写通用的实现逻辑 -->

**方法一:分组统计 + 连接**

我们可以先统计每个经理的直接下属人数,然后再连接 `Employee` 表,找出直接下属人数大于等于 $5$ 的经理。

<!-- tabs:start -->

### **SQL**

```sql
# Write your MySQL query statement below
SELECT
name
SELECT name
FROM
Employee AS e1
Employee
JOIN (
SELECT
managerId
FROM Employee
WHERE managerId IS NOT NULL
GROUP BY managerId
HAVING COUNT(1) >= 5
) AS e2
ON e1.id = e2.managerId;
```

```sql
# Write your MySQL query statement below
WITH
T AS (
SELECT
managerId,
COUNT(1) OVER (PARTITION BY managerId) AS cnt
SELECT managerId AS id, COUNT(1) AS cnt
FROM Employee
)
SELECT DISTINCT name
FROM
Employee AS e
JOIN T AS t ON e.id = t.managerId
WHERE cnt >= 5;
GROUP BY 1
HAVING cnt >= 5
) AS t
USING (id);
```

<!-- tabs:end -->
Original file line number Diff line number Diff line change
Expand Up @@ -55,41 +55,26 @@ Employee table:

## Solutions

**Solution 1: Grouping and Joining**

We can first count the number of direct subordinates for each manager, and then join the `Employee` table to find the managers whose number of direct subordinates is greater than or equal to $5$.

<!-- tabs:start -->

### **SQL**

```sql
# Write your MySQL query statement below
SELECT
name
SELECT name
FROM
Employee AS e1
Employee
JOIN (
SELECT
managerId
FROM Employee
WHERE managerId IS NOT NULL
GROUP BY managerId
HAVING COUNT(1) >= 5
) AS e2
ON e1.id = e2.managerId;
```

```sql
# Write your MySQL query statement below
WITH
T AS (
SELECT
managerId,
COUNT(1) OVER (PARTITION BY managerId) AS cnt
SELECT managerId AS id, COUNT(1) AS cnt
FROM Employee
)
SELECT DISTINCT name
FROM
Employee AS e
JOIN T AS t ON e.id = t.managerId
WHERE cnt >= 5;
GROUP BY 1
HAVING cnt >= 5
) AS t
USING (id);
```

<!-- tabs:end -->
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
# Write your MySQL query statement below
WITH
T AS (
SELECT
managerId,
COUNT(1) OVER (PARTITION BY managerId) AS cnt
FROM Employee
)
SELECT DISTINCT name
SELECT name
FROM
Employee AS e
JOIN T AS t ON e.id = t.managerId
WHERE cnt >= 5;
Employee
JOIN (
SELECT managerId AS id, COUNT(1) AS cnt
FROM Employee
GROUP BY 1
HAVING cnt >= 5
) AS t
USING (id);
8 changes: 6 additions & 2 deletions solution/0600-0699/0620.Not Boring Movies/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ id 是该表的主键(具有唯一值的列)。

<!-- 这里可写通用的实现逻辑 -->

**方法一:条件筛选 + 排序**

我们可以使用 `WHERE` 子句筛选出 `description` 不为 `boring`,并且 `id` 为奇数的记录,然后使用 `ORDER BY` 子句对结果按照 `rating` 降序排序。

<!-- tabs:start -->

### **SQL**
Expand All @@ -68,8 +72,8 @@ id 是该表的主键(具有唯一值的列)。
# Write your MySQL query statement below
SELECT *
FROM Cinema
WHERE description != 'boring' AND id % 2 = 1
ORDER BY rating DESC;
WHERE description != 'boring' AND id & 1 = 1
ORDER BY 4 DESC;
```

<!-- tabs:end -->
8 changes: 6 additions & 2 deletions solution/0600-0699/0620.Not Boring Movies/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ We have three movies with odd-numbered IDs: 1, 3, and 5. The movie with ID = 3 i

## Solutions

**Solution 1: Conditional Filtering + Sorting**

We can use the `WHERE` clause to filter out the records where `description` is not `boring` and `id` is odd, and then use the `ORDER BY` clause to sort the result in descending order by `rating`.

<!-- tabs:start -->

### **SQL**
Expand All @@ -64,8 +68,8 @@ We have three movies with odd-numbered IDs: 1, 3, and 5. The movie with ID = 3 i
# Write your MySQL query statement below
SELECT *
FROM Cinema
WHERE description != 'boring' AND id % 2 = 1
ORDER BY rating DESC;
WHERE description != 'boring' AND id & 1 = 1
ORDER BY 4 DESC;
```

<!-- tabs:end -->
4 changes: 2 additions & 2 deletions solution/0600-0699/0620.Not Boring Movies/Solution.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Write your MySQL query statement below
SELECT *
FROM Cinema
WHERE description != 'boring' AND id % 2 = 1
ORDER BY rating DESC;
WHERE description != 'boring' AND id & 1 = 1
ORDER BY 4 DESC;
9 changes: 7 additions & 2 deletions solution/1200-1299/1251.Average Selling Price/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,19 +84,24 @@ UnitsSold table:

<!-- 这里可写通用的实现逻辑 -->

**方法一:左连接 + 分组统计**

我们可以使用左连接,将 `Prices` 表和 `UnitsSold` 表连接起来,连接条件为 `product_id` 相等,并且 `purchase_date``start_date``end_date` 之间。然后使用 `GROUP BY` 子句对 `product_id` 进行分组,使用 `AVG` 函数计算平均价格。注意,如果某个产品没有销售记录,那么 `AVG` 函数会返回 `NULL`,因此我们可以使用 `IFNULL` 函数将其转换为 $0$。

<!-- tabs:start -->

### **SQL**

```sql
# Write your MySQL query statement below
SELECT
p.product_id,
IFNULL(ROUND(SUM(units * price) / SUM(units), 2), 0) AS average_price
IFNULL(ROUND(SUM(price * units) / SUM(units), 2), 0) AS average_price
FROM
Prices AS p
LEFT JOIN UnitsSold AS u
ON p.product_id = u.product_id AND purchase_date BETWEEN start_date AND end_date
GROUP BY product_id;
GROUP BY 1;
```

<!-- tabs:end -->
9 changes: 7 additions & 2 deletions solution/1200-1299/1251.Average Selling Price/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,24 @@ Average selling price for product 2 = ((200 * 15) + (30 * 30)) / 230 = 16.96

## Solutions

**Solution 1: Left Join + Grouping**

We can use a left join to join the `Prices` table and the `UnitsSold` table on `product_id`, and the condition that `purchase_date` is between `start_date` and `end_date`. Then, we can use `GROUP BY` to group by `product_id` for aggregation, and use the `AVG` function to calculate the average price. Note that if a product has no sales records, the `AVG` function will return `NULL`, so we can use the `IFNULL` function to convert it to $0$.

<!-- tabs:start -->

### **SQL**

```sql
# Write your MySQL query statement below
SELECT
p.product_id,
IFNULL(ROUND(SUM(units * price) / SUM(units), 2), 0) AS average_price
IFNULL(ROUND(SUM(price * units) / SUM(units), 2), 0) AS average_price
FROM
Prices AS p
LEFT JOIN UnitsSold AS u
ON p.product_id = u.product_id AND purchase_date BETWEEN start_date AND end_date
GROUP BY product_id;
GROUP BY 1;
```

<!-- tabs:end -->
5 changes: 3 additions & 2 deletions solution/1200-1299/1251.Average Selling Price/Solution.sql
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Write your MySQL query statement below
SELECT
p.product_id,
IFNULL(ROUND(SUM(units * price) / SUM(units), 2), 0) AS average_price
IFNULL(ROUND(SUM(price * units) / SUM(units), 2), 0) AS average_price
FROM
Prices AS p
LEFT JOIN UnitsSold AS u
ON p.product_id = u.product_id AND purchase_date BETWEEN start_date AND end_date
GROUP BY product_id;
GROUP BY 1;
20 changes: 10 additions & 10 deletions solution/1200-1299/1280.Students and Examinations/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,23 +123,23 @@ John 参加了数学、物理、编程测试各 1 次。

<!-- 这里可写通用的实现逻辑 -->

**方法一:两次连接 + 分组统计**

我们可以先连接 `Students` 表和 `Subjects` 表,得到所有学生和所有科目的组合,然后再连接 `Examinations` 表,连接条件为 `student_id``subject_name`,这样就得到了每个学生参加每一门科目测试的次数,最后按 `student_id``subject_name` 分组统计即可。

<!-- tabs:start -->

### **SQL**

```sql
# Write your MySQL query statement below
SELECT
a.student_id,
student_name,
b.subject_name,
COUNT(c.subject_name) AS attended_exams
SELECT student_id, student_name, subject_name, COUNT(e.student_id) AS attended_exams
FROM
Students AS a
CROSS JOIN Subjects AS b
LEFT JOIN Examinations AS c ON a.student_id = c.student_id AND b.subject_name = c.subject_name
GROUP BY a.student_id, b.subject_name
ORDER BY a.student_id, b.subject_name;
Students
JOIN Subjects
LEFT JOIN Examinations AS e USING (student_id, subject_name)
GROUP BY 1, 3
ORDER BY 1, 3;
```

<!-- tabs:end -->
20 changes: 10 additions & 10 deletions solution/1200-1299/1280.Students and Examinations/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,23 +120,23 @@ John attended the Math exam 1 time, the Physics exam 1 time, and the Programming

## Solutions

**Solution 1: Two Joins + Grouping**

We can first join the `Students` table and the `Subjects` table to obtain all combinations of students and subjects, and then join the `Examinations` table with the condition of `student_id` and `subject_name`. This way, we can get the number of times each student has taken each subject's test. Finally, we can group by `student_id` and `subject_name` to count the number of times each student has taken each subject's test.

<!-- tabs:start -->

### **SQL**

```sql
# Write your MySQL query statement below
SELECT
a.student_id,
student_name,
b.subject_name,
COUNT(c.subject_name) AS attended_exams
SELECT student_id, student_name, subject_name, COUNT(e.student_id) AS attended_exams
FROM
Students AS a
CROSS JOIN Subjects AS b
LEFT JOIN Examinations AS c ON a.student_id = c.student_id AND b.subject_name = c.subject_name
GROUP BY a.student_id, b.subject_name
ORDER BY a.student_id, b.subject_name;
Students
JOIN Subjects
LEFT JOIN Examinations AS e USING (student_id, subject_name)
GROUP BY 1, 3
ORDER BY 1, 3;
```

<!-- tabs:end -->
16 changes: 6 additions & 10 deletions solution/1200-1299/1280.Students and Examinations/Solution.sql
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
# Write your MySQL query statement below
SELECT
a.student_id,
student_name,
b.subject_name,
COUNT(c.subject_name) AS attended_exams
SELECT student_id, student_name, subject_name, COUNT(e.student_id) AS attended_exams
FROM
Students AS a
CROSS JOIN Subjects AS b
LEFT JOIN Examinations AS c ON a.student_id = c.student_id AND b.subject_name = c.subject_name
GROUP BY a.student_id, b.subject_name
ORDER BY a.student_id, b.subject_name;
Students
JOIN Subjects
LEFT JOIN Examinations AS e USING (student_id, subject_name)
GROUP BY 1, 3
ORDER BY 1, 3;
13 changes: 7 additions & 6 deletions solution/1900-1999/1934.Confirmation Rate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ Confirmations 表:

<!-- 这里可写通用的实现逻辑 -->

**方法一:左连接 + 分组统计**

我们可以使用左连接,将 `Signups` 表和 `Confirmations` 表按照 `user_id` 进行连接,然后使用 `GROUP BY``user_id` 进行分组统计。

<!-- tabs:start -->

### **SQL**
Expand All @@ -101,14 +105,11 @@ Confirmations 表:
# Write your MySQL query statement below
SELECT
user_id,
ROUND(
SUM(IF(action = 'confirmed', 1, 0)) / COUNT(1),
2
) AS confirmation_rate
ROUND(IFNULL(SUM(action = 'confirmed') / COUNT(1), 0), 2) AS confirmation_rate
FROM
Signups
SignUps
LEFT JOIN Confirmations USING (user_id)
GROUP BY user_id;
GROUP BY 1;
```

<!-- tabs:end -->
13 changes: 7 additions & 6 deletions solution/1900-1999/1934.Confirmation Rate/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ User 2 made 2 requests where one was confirmed and the other timed out. The conf

## Solutions

**Solution 1: Left Join + Grouping**

We can use a left join to join the `Signups` table and the `Confirmations` table on `user_id`, and then use `GROUP BY` to group by `user_id` for aggregation.

<!-- tabs:start -->

### **SQL**
Expand All @@ -97,14 +101,11 @@ User 2 made 2 requests where one was confirmed and the other timed out. The conf
# Write your MySQL query statement below
SELECT
user_id,
ROUND(
SUM(IF(action = 'confirmed', 1, 0)) / COUNT(1),
2
) AS confirmation_rate
ROUND(IFNULL(SUM(action = 'confirmed') / COUNT(1), 0), 2) AS confirmation_rate
FROM
Signups
SignUps
LEFT JOIN Confirmations USING (user_id)
GROUP BY user_id;
GROUP BY 1;
```

<!-- tabs:end -->
Loading

0 comments on commit 49ee3ff

Please sign in to comment.