Tác giả: Lê Trung Kiên lớp java 08
Email: lekien.2803.cg@gmail.com
SĐT: 0942096947
Link bài toán: https://leetcode.com/problems/group-sold-products-by-the-date/

1. Mở đầu

Xin chào các bạn, mình viết ra bài viết này để chia sẻ phương pháp giải cũng như tư duy của mình về bài toán này của leetcode. Phương pháp của mình có thể không phải là tối ưu nhất, tuy nhiên mình sẽ phân tích, chia nhỏ bài toán ra thành các module nhỏ hơn để dễ giải quyết cũng như giúp các bạn hiểu được các yêu cầu mà bài toán đưa ra.

2. Đề bài

Cho bảng Activities:

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| sell_date   | date    |
| product     | varchar |
+-------------+---------+
Không có khóa chính cho bảng này, có thể có các bản ghi trùng nhau.
Mỗi hàng của bảng này chứa tên sản phẩm và ngày sản phẩm được bán trên thị trường.

Hãy viết câu truy vấn lấy ra được ngày bán sản phẩm, số lượng sản phẩm khác biệt đã bán và tên những sản phẩm bán được ngày hôm đó.

Tên sản phẩm đã bán cho mỗi ngày phải được sắp xếp theo từ điển.

Trả về bảng kết quả sắp xếp theo sell_date.

Định dạng kết quả truy vấn nằm trong ví dụ sau.

Ví dụ 1:

Input: 
Activities table:
+------------+------------+
| sell_date  | product     |
+------------+------------+
| 2020-05-30 | Headphone  |
| 2020-06-01 | Pencil     |
| 2020-06-02 | Mask       |
| 2020-05-30 | Basketball |
| 2020-06-01 | Bible      |
| 2020-06-02 | Mask       |
| 2020-05-30 | T-Shirt    |
+------------+------------+
Output: 
+------------+----------+------------------------------+
| sell_date  | num_sold | products                     |
+------------+----------+------------------------------+
| 2020-05-30 | 3        | Basketball,Headphone,T-shirt |
| 2020-06-01 | 2        | Bible,Pencil                 |
| 2020-06-02 | 1        | Mask                         |
+------------+----------+------------------------------+
Explanation: 
Vào ngày 2020-05-30, những sản phẩm đã bán là (Headphone, Basketball, T-shirt), ta sắp xếp chúng theo thứ tự trong từ điển và ngăn cách nhau bằng dấu phẩy.
Vào ngày 2020-06-01, những sản phẩm đã bán là (Pencil, Bible), ta sắp xếp chúng theo thứ tự trong từ điển và ngăn cách nhau bằng dấu phẩy.
Vào ngày 2020-06-02, sản phẩm đã bán là (Mask), chỉ có một sản phẩm này nên ta trả về kết quả luôn.

3. Phân tích

Ấu kề, bài này có bảng kết quả trả về hơi khác với bảng gốc một chút.

Như các bạn đã thấy, ở cột đầu tiên chúng ta có sell_date cũng giống với bảng Activities, tuy nhiên thì bảng này có dữ liệu không tùng lặp và được sắp xếp theo thứ tự tăng dần. Vậy thì chúng ta sẽ sử dụng mệnh đề GROUP BY cho cột này để nhóm những dữ liệu trùng lặp lại.

Tiếp theo ta thấy có cột mới tên là num_sold, cột này chỉ ra số lượng sản phẩm khác biệt đã bán, như ở ví dụ thì ta thấy ngày 30/5/2022 bán được 3 sản phẩm khác nhau. Vậy để đếm được số lượng sản phẩm khác nhau trong ngày hôm đó thì ta sẽ dùng hàm COUNT() để đếm. Tuy nhiên thì làm thế nào để lấy ra được những sản phẩm khác nhau mà đếm? Lúc này chúng ta sẽ sử dụng từ khóa DISTINCT kết hợp với SELECT để lấy ra những bản ghi không trùng lặp.

Cuối cùng là cột products, tuy nhiên thì chúng ta phải liệt kê những sản phẩm ấy ra, ngăn cách chúng bằng dấu phẩy. Để làm được điều này, chúng ta cần đếm hàm group_concat(), với hàm này chúng ta có thể nối các bản ghi trong cột với nhau thành chuỗi, phân cách bằng dầu phẩy.

Vậy là xong! Hãy đến bước tiếp theo!

4. Code luôn cho nóng

Code của chúng ta sẽ như sau:

select sell_date, count(distinct product) as 'num_sold', group_concat(distinct product) as products
from activities
group by sell_date

5. Kết thúc

Qua bài viết này, mình đã chia sẻ cho các bạn cách mình tư duy khi giải bài tập trên leetcode. Hi vọng bài viết giúp ích cho các bạn trong cách tư duy để giải các bài tập khác. Xin cám ơn các bạn đã dành thời gian đọc và theo dõi. Peace!!!