Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

SQL Server CTE bên trái tham gia

Nếu không biết có bao nhiêu cấp trong hệ thống phân cấp?

Sau đó, thử thách như vậy thường được thực hiện thông qua một CTE đệ quy.

Đoạn mã mẫu:

--
-- Using table variables for testing reasons
--
declare @customertest table (cid int primary key, upid int);
declare @conftest table (cid int, confname varchar(6) default 'budget', confvalue int);
--
-- Sample data
--
insert into @customertest (cid, upid) values 
(1,0), (2,1), (3,1), (4,2), (5,2), (6,3), 
(7,5), (8,5), (9,8), (10,9);
insert into @conftest (cid, confvalue) values 
(1,1000), (2,700), (3,300), (4,100), (5,200), (6,300);

-- The customer that has his own budget, or not.
declare @customerID int = 10;

;with RCTE AS 
(
  --
  -- the recursive CTE starts from here. The seed records, as one could call it.
  --
  select cup.cid as orig_cid, 0 as lvl, cup.cid, cup.upid, budget.confvalue
  from @customertest as cup
  left join @conftest budget on (budget.cid = cup.cid and budget.confname = 'budget')
  where cup.cid = @customerID -- This is where we limit on the customer

  union all

  --
  -- This is where the Recursive CTE loops till it finds nothing new
  --
  select RCTE.orig_cid, RCTE.lvl+1, cup.cid, cup.upid, budget.confvalue
  from RCTE
  join @customertest as cup on (cup.cid = RCTE.upid)
  outer apply (select b.confvalue from @conftest b where b.cid = cup.cid and b.confname = 'budget') as budget
  where RCTE.confvalue is null -- Loop till a budget is found
)
select 
 orig_cid as cid, 
 confvalue
from RCTE
where confvalue is not null;    

Kết quả:

cid confvalue
--- ---------
 10       200

Btw, CTE đệ quy sử dụng ÁP DỤNG NGOÀI TRỜI vì MS SQL Server không cho phép sử dụng THAM GIA TRÁI OUTER ở đó.

Và nếu chắc chắn rằng có độ sâu tối đa 1 cấp cho khoản hỗ trợ với ngân sách?
Sau đó, chỉ cần kết hợp đơn giản bên trái và một liên kết sẽ thực hiện được.

Ví dụ:

select cup.cid, coalesce(cBudget.confvalue, upBudget.confvalue) as confvalue
from @customertest as cup
left join @conftest cBudget on (cBudget.cid = cup.cid and cBudget.confname = 'budget')
left join @conftest upBudget on (upBudget.cid = cup.upid and upBudget.confname = 'budget')
where cup.cid = 8;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách sao lưu hoặc tạo bảng mới từ Bảng SQL Server Hiện có trong SQL Server - Hướng dẫn sử dụng SQL Server / TSQL Phần 105

  2. Tìm thứ tự nút trong tài liệu XML trong SQL Server

  3. Giá trị cột danh tính đột nhiên nhảy đến 1001 trong máy chủ sql

  4. Cách trích xuất hoặc chuyển đổi dữ liệu thời gian từ một chuỗi trong SQL Server

  5. SQL Server 2008- Nhận các ràng buộc bảng