Skip to content

Commit c5962ae

Browse files
authored
feat: add solutions to lc problem: No.3230 (doocs#3302)
No.3230.Customer Purchasing Behavior Analysis
1 parent 8792fb2 commit c5962ae

File tree

7 files changed

+448
-0
lines changed

7 files changed

+448
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
---
2+
comments: true
3+
difficulty: 中等
4+
edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3230.Customer%20Purchasing%20Behavior%20Analysis/README.md
5+
---
6+
7+
<!-- problem:start -->
8+
9+
# [3230. Customer Purchasing Behavior Analysis 🔒](https://leetcode.cn/problems/customer-purchasing-behavior-analysis)
10+
11+
[English Version](/solution/3200-3299/3230.Customer%20Purchasing%20Behavior%20Analysis/README_EN.md)
12+
13+
## 题目描述
14+
15+
<!-- description:start -->
16+
17+
<p>Table: <code>Transactions</code></p>
18+
19+
<pre>
20+
+------------------+---------+
21+
| Column Name | Type |
22+
+------------------+---------+
23+
| transaction_id | int |
24+
| customer_id | int |
25+
| product_id | int |
26+
| transaction_date | date |
27+
| amount | decimal |
28+
+------------------+---------+
29+
transaction_id is the unique identifier for this table.
30+
Each row of this table contains information about a transaction, including the customer ID, product ID, date, and amount spent.
31+
</pre>
32+
33+
<p>Table: <code>Products</code></p>
34+
35+
<pre>
36+
+-------------+---------+
37+
| Column Name | Type |
38+
+-------------+---------+
39+
| product_id | int |
40+
| category | varchar |
41+
| price | decimal |
42+
+-------------+---------+
43+
product_id is the unique identifier for this table.
44+
Each row of this table contains information about a product, including its category and price.
45+
</pre>
46+
47+
<p>Write a solution to analyze customer purchasing behavior. For <strong>each customer</strong>, calculate:</p>
48+
49+
<ul>
50+
<li>The total amount spent.</li>
51+
<li>The number of transactions.</li>
52+
<li>The number of <strong>unique</strong> product categories purchased.</li>
53+
<li>The average amount spent.&nbsp;</li>
54+
<li>The <strong>most frequently</strong> purchased product category&nbsp;(if there is a tie, choose the one with the most recent transaction).</li>
55+
<li>A <strong>loyalty score</strong>&nbsp;defined as: (Number of transactions * 10) + (Total amount spent / 100).</li>
56+
</ul>
57+
58+
<p>Round <code>total_amount</code>, <code>avg_transaction_amount</code>, and <code>loyalty_score</code> to <code>2</code> decimal places.</p>
59+
60+
<p>Return <em>the result table ordered by</em> <code>loyalty_score</code> <em>in <strong>descending</strong> order</em>, <em>then by </em><code>customer_id</code><em> in <strong>ascending</strong> order</em>.</p>
61+
62+
<p>The query result format is in the following example.</p>
63+
64+
<p>&nbsp;</p>
65+
<p><strong class="example">Example:</strong></p>
66+
67+
<div class="example-block">
68+
<p><strong>Input:</strong></p>
69+
70+
<p><code>Transactions</code> table:</p>
71+
72+
<pre class="example-io">
73+
+----------------+-------------+------------+------------------+--------+
74+
| transaction_id | customer_id | product_id | transaction_date | amount |
75+
+----------------+-------------+------------+------------------+--------+
76+
| 1 | 101 | 1 | 2023-01-01 | 100.00 |
77+
| 2 | 101 | 2 | 2023-01-15 | 150.00 |
78+
| 3 | 102 | 1 | 2023-01-01 | 100.00 |
79+
| 4 | 102 | 3 | 2023-01-22 | 200.00 |
80+
| 5 | 101 | 3 | 2023-02-10 | 200.00 |
81+
+----------------+-------------+------------+------------------+--------+
82+
</pre>
83+
84+
<p><code>Products</code> table:</p>
85+
86+
<pre class="example-io">
87+
+------------+----------+--------+
88+
| product_id | category | price |
89+
+------------+----------+--------+
90+
| 1 | A | 100.00 |
91+
| 2 | B | 150.00 |
92+
| 3 | C | 200.00 |
93+
+------------+----------+--------+
94+
</pre>
95+
96+
<p><strong>Output:</strong></p>
97+
98+
<pre class="example-io">
99+
+-------------+--------------+-------------------+-------------------+------------------------+--------------+---------------+
100+
| customer_id | total_amount | transaction_count | unique_categories | avg_transaction_amount | top_category | loyalty_score |
101+
+-------------+--------------+-------------------+-------------------+------------------------+--------------+---------------+
102+
| 101 | 450.00 | 3 | 3 | 150.00 | C | 34.50 |
103+
| 102 | 300.00 | 2 | 2 | 150.00 | C | 23.00 |
104+
+-------------+--------------+-------------------+-------------------+------------------------+--------------+---------------+
105+
</pre>
106+
107+
<p><strong>Explanation:</strong></p>
108+
109+
<ul>
110+
<li>For customer 101:
111+
<ul>
112+
<li>Total amount spent: 100.00 + 150.00 + 200.00 = 450.00</li>
113+
<li>Number of transactions: 3</li>
114+
<li>Unique categories: A, B, C (3 categories)</li>
115+
<li>Average transaction amount: 450.00 / 3 = 150.00</li>
116+
<li>Top category: C (Customer 101 made 1 purchase each in categories A, B, and C. Since the count is the same for all categories, we choose the most recent transaction, which is category C on 2023-02-10)</li>
117+
<li>Loyalty score: (3 * 10) + (450.00 / 100) = 34.50</li>
118+
</ul>
119+
</li>
120+
<li>For customer 102:
121+
<ul>
122+
<li>Total amount spent: 100.00 + 200.00 = 300.00</li>
123+
<li>Number of transactions: 2</li>
124+
<li>Unique categories: A, C (2 categories)</li>
125+
<li>Average transaction amount: 300.00 / 2 = 150.00</li>
126+
<li>Top category: C (Customer 102 made 1 purchase each in categories A and C. Since the count is the same for both categories, we choose the most recent transaction, which is category C on 2023-01-22)</li>
127+
<li>Loyalty score: (2 * 10) + (300.00 / 100) = 23.00</li>
128+
</ul>
129+
</li>
130+
</ul>
131+
132+
<p><strong>Note:</strong> The output is ordered by loyalty_score in descending order, then by customer_id in ascending order.</p>
133+
</div>
134+
135+
<!-- description:end -->
136+
137+
## 解法
138+
139+
<!-- solution:start -->
140+
141+
### 方法一:分组 + 窗口函数 + 连接
142+
143+
我们首先将 `Transactions` 表和 `Products` 表连接起来,记录在临时表 `T` 中。
144+
145+
然后,我们使用 `T` 表计算每个用户在每个类别下的交易次数以及最近的交易日期,将结果保存在临时表 `P` 中。
146+
147+
接着,我们使用 `P` 表计算每个用户在每个类别下的交易次数的排名,将结果保存在临时表 `R` 中。
148+
149+
最后,我们使用 `T` 表和 `R` 表计算每个用户的总交易金额、交易次数、唯一类别数、平均交易金额、最常购买的类别、忠诚度分数,并按照忠诚度分数降序、用户 ID 升序的顺序返回结果。
150+
151+
<!-- tabs:start -->
152+
153+
#### MySQL
154+
155+
```sql
156+
# Write your MySQL query statement below
157+
WITH
158+
T AS (
159+
SELECT *
160+
FROM
161+
Transactions
162+
JOIN Products USING (product_id)
163+
),
164+
P AS (
165+
SELECT
166+
customer_id,
167+
category,
168+
COUNT(1) cnt,
169+
MAX(transaction_date) max_date
170+
FROM T
171+
GROUP BY 1, 2
172+
),
173+
R AS (
174+
SELECT
175+
customer_id,
176+
category,
177+
RANK() OVER (
178+
PARTITION BY customer_id
179+
ORDER BY cnt DESC, max_date DESC
180+
) rk
181+
FROM P
182+
)
183+
SELECT
184+
t.customer_id,
185+
ROUND(SUM(amount), 2) total_amount,
186+
COUNT(1) transaction_count,
187+
COUNT(DISTINCT t.category) unique_categories,
188+
ROUND(AVG(amount), 2) avg_transaction_amount,
189+
r.category top_category,
190+
ROUND(COUNT(1) * 10 + SUM(amount) / 100, 2) loyalty_score
191+
FROM
192+
T t
193+
JOIN R r ON t.customer_id = r.customer_id AND r.rk = 1
194+
GROUP BY 1
195+
ORDER BY 7 DESC, 1;
196+
```
197+
198+
<!-- tabs:end -->
199+
200+
<!-- solution:end -->
201+
202+
<!-- problem:end -->

0 commit comments

Comments
 (0)