Trong thế giới quản lý dữ liệu với Oracle, việc đánh số thứ tự cho các bản ghi là một thao tác phổ biến. Hai hàm thường được sử dụng cho mục đích này là ROW_NUMBER()
và ROWNUM
. Mặc dù cả hai đều tạo ra số thứ tự cho các hàng, nhưng chúng hoạt động theo cơ chế khác nhau và phù hợp với các tình huống sử dụng riêng biệt. Hiểu rõ sự khác biệt giữa ROW_NUMBER()
và ROWNUM
là chìa khóa để viết truy vấn SQL hiệu quả và chính xác trong Oracle.
ROWNUM: Đánh Số Thứ Tự Đơn Giản
ROWNUM
là một hàm giả cột (pseudocolumn) trong Oracle, tự động gán số thứ tự cho mỗi hàng được trả về từ một truy vấn. Số thứ tự này đại diện cho thứ tự các hàng được truy xuất, bắt đầu từ 1.
Ví dụ:
SELECT ROWNUM, employee_name, salary
FROM employees;
Truy vấn này sẽ trả về danh sách nhân viên cùng với số thứ tự được gán bởi ROWNUM
, bắt đầu từ 1 cho nhân viên đầu tiên được truy xuất.
Tuy nhiên, ROWNUM
có một số hạn chế:
-
Đánh số trước khi sắp xếp:
ROWNUM
được gán trước khi bất kỳ điều khoảnORDER BY
nào được áp dụng. Điều này có nghĩa là nếu bạn sử dụngROWNUM
sau khi sắp xếp kết quả, số thứ tự sẽ không phản ánh thứ tự mong muốn. -
Giới hạn kết quả:
ROWNUM
thường được sử dụng để giới hạn số lượng bản ghi được trả về. Ví dụ, để lấy 5 nhân viên có lương cao nhất, bạn có thể sử dụng:
SELECT ROWNUM, employee_name, salary
FROM employees
WHERE ROWNUM <= 5;
Tuy nhiên, việc sử dụng ROWNUM > n
(với n là một số nguyên) sẽ không trả về kết quả nào.
ROW_NUMBER(): Linh Hoạt và Mạnh Mẽ Hơn
ROW_NUMBER()
là một hàm phân tích (analytic function) được giới thiệu trong Oracle 8i, cung cấp khả năng đánh số thứ tự linh hoạt và mạnh mẽ hơn ROWNUM
.
Cú pháp:
ROW_NUMBER() OVER ( [PARTITION BY partition_expression] ORDER BY sort_expression)
- PARTITION BY: Cho phép bạn chia kết quả thành các phân vùng (partition) dựa trên một biểu thức. Số thứ tự sẽ được đặt lại cho mỗi phân vùng.
- ORDER BY: Xác định thứ tự sắp xếp các hàng trong mỗi phân vùng trước khi gán số thứ tự.
Ví dụ:
Để lấy 3 nhân viên có lương cao nhất trong mỗi phòng ban, bạn có thể sử dụng ROW_NUMBER()
kết hợp với PARTITION BY
:
SELECT department_id, employee_name, salary,
ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) as rn
FROM employees;
Trong truy vấn này:
PARTITION BY department_id
: Chia kết quả thành các phân vùng theo phòng ban.ORDER BY salary DESC
: Sắp xếp nhân viên trong mỗi phân vùng theo thứ tự lương giảm dần.ROW_NUMBER() OVER (...) as rn
: Gán số thứ tự (rn) cho mỗi nhân viên trong mỗi phân vùng, bắt đầu từ 1 cho nhân viên có lương cao nhất.
Khi Nào Nên Sử Dụng Hàm Nào?
Tình huống | ROWNUM |
ROW_NUMBER() |
---|---|---|
Đánh số thứ tự đơn giản cho kết quả truy vấn | Phù hợp | Có thể sử dụng, nhưng ROWNUM đơn giản hơn |
Giới hạn số lượng bản ghi trả về | Phù hợp | Có thể sử dụng, nhưng yêu cầu truy vấn con |
Đánh số thứ tự sau khi sắp xếp | Không phù hợp | Phù hợp |
Đánh số thứ tự trong các phân vùng | Không phù hợp | Phù hợp |
Kết Luận
Hiểu rõ sự khác biệt giữa ROWNUM
và ROW_NUMBER()
là rất quan trọng để viết truy vấn SQL hiệu quả trong Oracle. Trong khi ROWNUM
cung cấp cách đánh số thứ tự đơn giản, ROW_NUMBER()
mang đến sự linh hoạt và mạnh mẽ hơn với khả năng phân vùng và sắp xếp. Lựa chọn hàm phù hợp phụ thuộc vào yêu cầu cụ thể của bạn và cấu trúc dữ liệu.
Cần hỗ trợ thêm về Oracle SQL hoặc các chủ đề công nghệ khác?
Hãy liên hệ với chúng tôi:
- Số Điện Thoại: 0372999888
- Email: [email protected]
- Địa chỉ: 236 Cầu Giấy, Hà Nội.
Chúng tôi có đội ngũ chăm sóc khách hàng 24/7.