r
của bạn bí danh và rights
bảng mà nó đề cập đến không nằm trong phạm vi cho dạng xem nội tuyến mà bạn đang tạo. Bạn cần tạo cấu trúc phân cấp mà bạn vẫn có thể thực hiện trong chế độ xem nội tuyến, rồi nối cấu trúc đó với rights
bảng thông qua folderid
của nó .
Bạn có thể lấy thứ bậc từ:
select connect_by_root(folderid) as rootid, folderid,
sys_connect_by_path(folderid, '/') as path
from folders
connect by parentfolderid = prior folderid
order by rootid, path;
ROOTID FOLDERID PATH
---------- ---------- ------------------------------
5162 5162 /5162
5162 28568 /5162/28568
5162 6343 /5162/6343
5534 5534 /5534
5534 41578 /5534/41578
5534 113867 /5534/41578/113867
5534 127030 /5534/41578/127030
5534 5162 /5534/5162
5534 28568 /5534/5162/28568
5534 6343 /5534/5162/6343
5534 5538 /5534/5538
5538 5538 /5538
...
Đó là khá nhiều những gì bạn đang làm, nhưng điều này tìm thấy tất cả các con cháu từ bất kỳ điểm xuất phát nào và cũng ghi lại điểm bắt đầu là rootid
. (Tôi đã đưa vào path
quá chỉ để hình dung hệ thống phân cấp; bạn dường như không muốn điều đó trong kết quả).
Sau đó, bạn có thể kết hợp nó với bảng quyền của mình, trong đó folderid
của mỗi người dùng khớp với bất kỳ rootid
nào . Điều đó sẽ liệt kê các bản sao (ví dụ:685 có thể đến trực tiếp 5538 hoặc qua 5534), vì vậy bạn có thể sử dụng distinct
để loại bỏ những:
select distinct r.userid, f.folderid
from rights r
join (
select connect_by_root(folderid) as rootid, folderid
from folders
connect by prior folderid = parentfolderid
) f
on f.rootid = r.folderid
order by r.userid, f.folderid;
Mà với dữ liệu của bạn có 16 kết hợp riêng biệt:
USERID FOLDERID
---------- ----------
685 5162
685 5534
685 5538
685 6343
685 28568
685 41578
685 113867
685 127030
686 5162
686 6343
686 28568
686 41578
686 113867
686 127030
725 113867
725 127030
Bạn cũng có thể sử dụng tính toán truy vấn con đệ quy thay vì truy vấn phân cấp:
with rcte (userid, folderid) as (
select r.userid, f.folderid
from rights r
join folders f on f.folderid = r.folderid
union all
select rcte.userid, f.folderid
from rcte
join folders f on f.parentfolderid = rcte.folderid
)
select distinct userid, folderid
from rcte
order by userid, folderid;
Thành viên liên kết là một phép nối đơn giản giữa hai bảng để nhận các quyền cấp cao nhất. Sau đó, thành viên đệ quy tìm kiếm bất kỳ quyền con nào của bất kỳ quyền nào đã được tìm thấy. Kết quả giống nhau, cách tiếp cận hơi khác.