Skip to content

Commit cb593b9

Browse files
authored
feat: add sql solutions to lc problems: No.2993~2995 (doocs#2182)
* No.2993.Friday Purchases I * No.2994.Friday Purchases II * No.2995.Viewers Turned Streamers
1 parent ab7bf42 commit cb593b9

File tree

12 files changed

+2312
-3117
lines changed

12 files changed

+2312
-3117
lines changed

.prettierrc

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949
"solution/2600-2699/2686.Immediate Food Delivery III/Solution.sql",
5050
"solution/2400-2499/2494.Merge Overlapping Events in the Same Hall/Solution.sql",
5151
"solution/2700-2799/2752.Customers with Maximum Number of Transactions on Consecutive Days/Solution.sql",
52-
"solution/2700-2799/2793.Status of Flight Tickets/Solution.sql"
52+
"solution/2700-2799/2793.Status of Flight Tickets/Solution.sql",
53+
"solution/2900-2999/2994.Friday Purchases II/Solution.sql"
5354
],
5455
"options": {
5556
"parser": "bigquery"

package-lock.json

+2,135-3,109
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"lint-staged": "^13.2.2",
1717
"prettier": "^2.8.8",
1818
"prettier-plugin-rust": "^0.1.9",
19-
"prettier-plugin-sql-cst": "^0.8.2"
19+
"prettier-plugin-sql-cst": "^0.10.0"
2020
},
2121
"lint-staged": {
2222
"*.{js,ts,php,sql,rs,md}": "prettier --write",

solution/2900-2999/2993.Friday Purchases I/README.md

+19-1
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,32 @@ Output table is ordered by week_of_month in ascending order.</pre>
6363

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

66+
**方法一:日期函数**
67+
68+
我们用到的日期函数有:
69+
70+
- `DATE_FORMAT(date, format)`:将日期格式化为字符串
71+
- `DAYOFWEEK(date)`:返回日期对应的星期几,1 代表星期日,2 代表星期一,以此类推
72+
- `DAYOFMONTH(date)`:返回日期对应的月份中的第几天
73+
74+
我们先用 `DATE_FORMAT` 函数将日期格式化为 `YYYYMM` 的形式,然后筛选出 2023 年 11 月且是星期五的记录,然后将记录按照 `purchase_date` 分组,计算出每个星期五的总消费金额。
75+
6676
<!-- tabs:start -->
6777

6878
### **SQL**
6979

7080
<!-- 这里可写当前语言的特殊实现逻辑 -->
7181

7282
```sql
73-
83+
# Write your MySQL query statement below
84+
SELECT
85+
CEIL(DAYOFMONTH(purchase_date) / 7) AS week_of_month,
86+
purchase_date,
87+
SUM(amount_spend) AS total_amount
88+
FROM Purchases
89+
WHERE DATE_FORMAT(purchase_date, '%Y%m') = '202311' AND DAYOFWEEK(purchase_date) = 6
90+
GROUP BY 2
91+
ORDER BY 1;
7492
```
7593

7694
<!-- tabs:end -->

solution/2900-2999/2993.Friday Purchases I/README_EN.md

+19-1
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,30 @@ Output table is ordered by week_of_month in ascending order.</pre>
5959

6060
## Solutions
6161

62+
**Solution 1: Date Functions**
63+
64+
The date functions we use include:
65+
66+
- `DATE_FORMAT(date, format)`: Formats a date as a string
67+
- `DAYOFWEEK(date)`: Returns the day of the week for a date, where 1 represents Sunday, 2 represents Monday, and so on
68+
- `DAYOFMONTH(date)`: Returns the day of the month for a date
69+
70+
First, we use the `DATE_FORMAT` function to format the date in the form of `YYYYMM`, then filter out the records of November 2023 that fall on a Friday. Next, we group the records by `purchase_date` and calculate the total consumption amount for each Friday.
71+
6272
<!-- tabs:start -->
6373

6474
### **SQL**
6575

6676
```sql
67-
77+
# Write your MySQL query statement below
78+
SELECT
79+
CEIL(DAYOFMONTH(purchase_date) / 7) AS week_of_month,
80+
purchase_date,
81+
SUM(amount_spend) AS total_amount
82+
FROM Purchases
83+
WHERE DATE_FORMAT(purchase_date, '%Y%m') = '202311' AND DAYOFWEEK(purchase_date) = 6
84+
GROUP BY 2
85+
ORDER BY 1;
6886
```
6987

7088
<!-- tabs:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Write your MySQL query statement below
2+
SELECT
3+
CEIL(DAYOFMONTH(purchase_date) / 7) AS week_of_month,
4+
purchase_date,
5+
SUM(amount_spend) AS total_amount
6+
FROM Purchases
7+
WHERE DATE_FORMAT(purchase_date, '%Y%m') = '202311' AND DAYOFWEEK(purchase_date) = 6
8+
GROUP BY 2
9+
ORDER BY 1;

solution/2900-2999/2994.Friday Purchases II/README.md

+22-1
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,35 @@ Output table is ordered by week_of_month in ascending order.</pre>
6565

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

68+
**方法一:递归 + 左连接 + 日期函数**
69+
70+
我们可以使用递归生成一个包含 2023 年 11 月所有日期的表 `T`,然后使用左连接将 `T``Purchases` 表按照日期进行连接,最后按照题目要求进行分组求和即可。
71+
6872
<!-- tabs:start -->
6973

7074
### **SQL**
7175

7276
<!-- 这里可写当前语言的特殊实现逻辑 -->
7377

7478
```sql
75-
79+
WITH RECURSIVE
80+
T AS (
81+
SELECT '2023-11-01' AS purchase_date
82+
UNION
83+
SELECT purchase_date + INTERVAL 1 DAY
84+
FROM T
85+
WHERE purchase_date < '2023-11-30'
86+
)
87+
SELECT
88+
CEIL(DAYOFMONTH(purchase_date) / 7) AS week_of_month,
89+
purchase_date,
90+
IFNULL(SUM(amount_spend), 0) AS total_amount
91+
FROM
92+
T
93+
LEFT JOIN Purchases USING (purchase_date)
94+
WHERE DAYOFWEEK(purchase_date) = 6
95+
GROUP BY 2
96+
ORDER BY 1;
7697
```
7798

7899
<!-- tabs:end -->

solution/2900-2999/2994.Friday Purchases II/README_EN.md

+22-1
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,33 @@ Output table is ordered by week_of_month in ascending order.</pre>
6161

6262
## Solutions
6363

64+
**Solution 1: Recursion + Left Join + Date Functions**
65+
66+
We can generate a table `T` that contains all dates in November 2023 using recursion, then use a left join to connect `T` and the `Purchases` table by date. Finally, group and sum according to the requirements of the problem.
67+
6468
<!-- tabs:start -->
6569

6670
### **SQL**
6771

6872
```sql
69-
73+
WITH RECURSIVE
74+
T AS (
75+
SELECT '2023-11-01' AS purchase_date
76+
UNION
77+
SELECT purchase_date + INTERVAL 1 DAY
78+
FROM T
79+
WHERE purchase_date < '2023-11-30'
80+
)
81+
SELECT
82+
CEIL(DAYOFMONTH(purchase_date) / 7) AS week_of_month,
83+
purchase_date,
84+
IFNULL(SUM(amount_spend), 0) AS total_amount
85+
FROM
86+
T
87+
LEFT JOIN Purchases USING (purchase_date)
88+
WHERE DAYOFWEEK(purchase_date) = 6
89+
GROUP BY 2
90+
ORDER BY 1;
7091
```
7192

7293
<!-- tabs:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
WITH RECURSIVE
2+
T AS (
3+
SELECT '2023-11-01' AS purchase_date
4+
UNION
5+
SELECT purchase_date + INTERVAL 1 DAY
6+
FROM T
7+
WHERE purchase_date < '2023-11-30'
8+
)
9+
SELECT
10+
CEIL(DAYOFMONTH(purchase_date) / 7) AS week_of_month,
11+
purchase_date,
12+
IFNULL(SUM(amount_spend), 0) AS total_amount
13+
FROM
14+
T
15+
LEFT JOIN Purchases USING (purchase_date)
16+
WHERE DAYOFWEEK(purchase_date) = 6
17+
GROUP BY 2
18+
ORDER BY 1;

solution/2900-2999/2995.Viewers Turned Streamers/README.md

+23-1
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,36 @@ Sessions table:
6565

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

68+
**方法一:窗口函数 + 等值连接**
69+
70+
我们可以用窗口函数 `RANK()` 按照 `user_id` 维度,对每个会话进行排名,记录在表 `T` 中,然后再将 `T``Sessions` 表按照 `user_id` 进行等值连接,并且筛选出 `T` 中排名为 1 的记录,并且 `session_type``Viewer``Sessions` 表中 `session_type``Streamer` 的记录,最后按照 `user_id` 进行分组求和即可。
71+
6872
<!-- tabs:start -->
6973

7074
### **SQL**
7175

7276
<!-- 这里可写当前语言的特殊实现逻辑 -->
7377

7478
```sql
75-
79+
# Write your MySQL query statement below
80+
WITH
81+
T AS (
82+
SELECT
83+
user_id,
84+
session_type,
85+
RANK() OVER (
86+
PARTITION BY user_id
87+
ORDER BY session_start
88+
) AS rk
89+
FROM Sessions
90+
)
91+
SELECT user_id, COUNT(1) AS sessions_count
92+
FROM
93+
T AS t
94+
JOIN Sessions AS s USING (user_id)
95+
WHERE rk = 1 AND t.session_type = 'Viewer' AND s.session_type = 'Streamer'
96+
GROUP BY 1
97+
ORDER BY 2 DESC, 1 DESC;
7698
```
7799

78100
<!-- tabs:end -->

solution/2900-2999/2995.Viewers Turned Streamers/README_EN.md

+23-1
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,34 @@ Output table is ordered by sessions count and user_id in descending order.
6060

6161
## Solutions
6262

63+
**Solution 1: Window Function + Equi-Join**
64+
65+
We can use the window function `RANK()` to rank each session by `user_id` dimension, and record it in table `T`. Then, we equi-join `T` and the `Sessions` table by `user_id`, and filter out the records in `T` where the rank is 1, and `session_type` is `Viewer`, and `session_type` in the `Sessions` table is `Streamer`. Finally, we group by `user_id` and sum up.
66+
6367
<!-- tabs:start -->
6468

6569
### **SQL**
6670

6771
```sql
68-
72+
# Write your MySQL query statement below
73+
WITH
74+
T AS (
75+
SELECT
76+
user_id,
77+
session_type,
78+
RANK() OVER (
79+
PARTITION BY user_id
80+
ORDER BY session_start
81+
) AS rk
82+
FROM Sessions
83+
)
84+
SELECT user_id, COUNT(1) AS sessions_count
85+
FROM
86+
T AS t
87+
JOIN Sessions AS s USING (user_id)
88+
WHERE rk = 1 AND t.session_type = 'Viewer' AND s.session_type = 'Streamer'
89+
GROUP BY 1
90+
ORDER BY 2 DESC, 1 DESC;
6991
```
7092

7193
<!-- tabs:end -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Write your MySQL query statement below
2+
WITH
3+
T AS (
4+
SELECT
5+
user_id,
6+
session_type,
7+
RANK() OVER (
8+
PARTITION BY user_id
9+
ORDER BY session_start
10+
) AS rk
11+
FROM Sessions
12+
)
13+
SELECT user_id, COUNT(1) AS sessions_count
14+
FROM
15+
T AS t
16+
JOIN Sessions AS s USING (user_id)
17+
WHERE rk = 1 AND t.session_type = 'Viewer' AND s.session_type = 'Streamer'
18+
GROUP BY 1
19+
ORDER BY 2 DESC, 1 DESC;

0 commit comments

Comments
 (0)