+1

Phân biệt một số khái niệm trong SQL (Phần 2)

Self Join là gì và tại sao nó cần thiết? SELF JOIN trong SQL được sử dụng để kết hợp một bảng với chính nó như khi coi bảng đó là hai bảng, thay tên tạm thời ít nhất một bảng trong lệnh SQL. Cú pháp chung:

SELECT a.ten_cot, b.ten_cot...
FROM bang1 a, bang1 b
WHERE a.field_chung = b.field_chung;

Trong ví dụ về bảng nhân viên ở bài trước, chúng ta đã giữ lại manager ID của từng employee trong cùng hàng với employee . Đây là một ví dụ về một hệ thống phân cấp (trong trường hợp này là phân cấp quản lý nhân viên) được lưu trữ trong bảng RDBMS. Bây giờ, giả sử nếu chúng ta cần in tên của người quản lý của mỗi nhân viên ngay bên cạnh nhân viên, chúng ta có thể sử dụng self join. Xem ví dụ dưới đây:

SELECT e.name EMPLOYEE, m.name MANAGER
FROM EMPLOYEE e, EMPLOYEE m
WHERE e.mgr_id = m.id (+)

Lý do duy nhất chúng ta đã thực hiện left outer join (thay vì INNER JOIN) là vì có một nhân viên (Hash) trong bảng này mà không có người quản lý. Nếu chúng ta thực hiện inner join, nhân viên này sẽ không hiển thị.

Làm thế nào để tạo ra row number trong SQL mà không cần đến ROWNUM Row number là một dãy tuần tự các số, việc tạo ra row number bằng SQL không dễ dàng. Phương pháp dưới đây chỉ hoạt động nếu có ít nhất một cột duy nhất trong bảng.

SELECT name, sal, (SELECT COUNT(*)  FROM EMPLOYEE i WHERE o.name >= i.name) row_num
FROM EMPLOYEE o
order by row_num

Làm thế nào để lấy 5 records từ một table? Với Oracle:

SELECT * 
FROM EMP
WHERE ROWNUM <= 5;

Với SQL Server:

SELECT TOP 5 * FROM EMP;

Sự khác biệt giữa ROWNUM pseudo column và ROW_NUMBER() function ROW_NUMBER() là một chức năng phân tích được sử dụng kết hợp với mệnh đề OVER(), trong đó chúng ta có thể chỉ định ORDER BY và PARTITION BY. Giả sử nếu bạn muốn tạo ra các số hàng theo thứ tự lương của nhân viên tăng dần thì ROWNUM sẽ không hoạt động. Nhưng bạn có thể sử dụng ROW_NUMBER() OVER() như dưới đây:

SELECT name, sal, row_number() over(order by sal desc) rownum_by_sal
FROM EMPLOYEE o

Sự khác biệt giữa ROWNUM, RANK và DENSE_RANK? ROW_NUMBER dùng để trả về một con số tuần tự, unique gắn với mỗi bản ghi (từ 1 đến N) RANK: không trả về các số unique và tuần tự. Nếu hai bản ghi có vị trí thứ hai thì sẽ không có bản ghi nào xếp hạng thứ 3. Ví dụ:

SELECT name, sal, rank() over(order by sal desc) rank_by_sal
FROM EMPLOYEE o

DENSE_RANK: cũng giống RANK, cũng không trả về các số unique, nhưng trả về con số tuần tự. Mặc dù có hai bản ghi có cùng vị trí thứ hai, thì các bản ghi tiếp theo rank vẫn được đánh số từ thứ 3. Ví dụ:

SELECT name, sal, dense_rank() over(order by sal desc) dense_rank_by_sal
FROM EMPLOYEE o

Nguồn tham khảo: https://dwbi.org/database/sql/72-top-20-sql-interview-questions-with-answers http://imic.edu.vn/kien-thuc/10531/self-join-trong-sql.html


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.