- shares
- Facebook Messenger
- Gmail
- Viber
- Skype
Bài viết này hướng bạn cách sử dụng lệnh group để lấy một lượng bản ghi trong một nhóm group.
Giả sử ta có bảng fruits sau đây:
+——–+————+——-+
| type | variety | price |
+——–+————+——-+
| apple | gala | 2.79 |
| apple | fuji | 0.24 |
| apple | limbertwig | 2.87 |
| orange | valencia | 3.59 |
| orange | navel | 9.36 |
| pear | bradford | 6.05 |
| pear | bartlett | 2.14 |
| cherry | bing | 2.55 |
| cherry | chelan | 6.33 |
+——–+————+——-+
Bài toán 1: Selecting the one maximum row from each group
Ở trong ví dụ này: Tôi muốn lựa chọn hoa quả có giá thấp nhất trong mỗi loại như: táo, cam,..
Kết quả mong đợi:
+——–+———-+——-+
| type | variety | price |
+——–+———-+——-+
| apple | fuji | 0.24 |
| orange | valencia | 3.59 |
| pear | bartlett | 2.14 |
| cherry | bing | 2.55 |
+——–+———-+——-+
Cách 1:
– Bước đầu tiên sẽ lấy 2 trường type và price: nhóm trường type lại và lấy dòng có price thấp nhất.
SELECT TYPE, MIN(price) AS minprice FROM fruits GROUP BY TYPE;
Chú ý: Bước 1 không phải kết quả cuối cùng. Vì lệnh group mà lấy giá trị min là độc lập, không cùng 1 bản ghi. Do vậy phải dùng đến bước 2.
– Bước tiếp theo nối bảng fruits với bảng mới tạo ra ở trên. Ta có câu lệnh cuối cùng:
SELECT f.type, f.variety, f.price FROM ( SELECT TYPE, MIN(price) AS minprice FROM fruits GROUP BY TYPE ) AS x INNER JOIN fruits AS f ON f.type = x.type AND f.price = x.minprice;
Cách 2:
Có một cách khác để làm điều này là lấy từng record với điều kiện where với alias của bảng này. Nhưng hiểu bản chất là lấy dữ liệu để so sánh với một bảng khác cũng chính là bảng này.
SELECT TYPE, variety, price FROM fruits WHERE price = (SELECT MIN(price) FROM fruits AS f WHERE f.type = fruits.type);
Kết quả cuối cùng là:
+——–+———-+——-+
| type | variety | price |
+——–+———-+——-+
| apple | fuji | 0.24 |
| orange | valencia | 3.59 |
| pear | bartlett | 2.14 |
| cherry | bing | 2.55 |
+——–+———-+——-+
Bài toán 2: Select the top N rows from each group
Lúc này bài toán trên trở thành, lựa chọn 2 hoa quả rẻ nhất trong mỗi loại.
Yêu cầu bài toán lấy dòng có giới hạn trong từng group do vậy loại bỏ trường hợp dùng join mà dùng where.
Mã giả:
tìm record có price nhỏ nhất với mỗi nhóm hoặc price>price nhỏ nhất (theo chiều lớn dần giá nhỏ nhất) ->sẽ liệt kê các record có price lớn dần trong mỗi nhóm.
Cách này có thể không đúng với yêu cầu bài toán.
Có thể dùng where không trực tiếp so sánh price, mà so sánh số lượng cần lấy, và các bản ghi vẫn được lấy theo cách ngầm với điều kiện price xắp xếp tăng dần.
Xem đoạn code dưới đây.
SELECT TYPE, variety, price FROM fruits WHERE ( SELECT COUNT(*) FROM fruits AS f WHERE f.type = fruits.type AND f.price <= fruits.price ) <= 2;
Chúc bạn thành công.
Nếu bạn thấy bài viết này hữu ích, hãy chia sẻ với bạn bè bằng cách nhấn nút chia sẻ ở bên dưới. Theo dõi chúng tôi trên Twitter và Facebook
- shares
- Facebook Messenger
- Gmail
- Viber
- Skype