Đến với SQL từ các ngôn ngữ lập trình khác, cấu trúc của truy vấn đệ quy trông khá kỳ quặc. Đi qua nó từng bước một, và nó dường như sụp đổ.
Hãy xem xét ví dụ đơn giản sau:
CREATE TABLE #NUMS
(N BIGINT);
INSERT INTO #NUMS
VALUES (3), (5), (7);
WITH R AS
(
SELECT N FROM #NUMS
UNION ALL
SELECT N*N AS N FROM R WHERE N*N < 10000000
)
SELECT N FROM R ORDER BY N;
Hãy đi qua nó.
Đầu tiên, thành viên neo thực thi và tập kết quả được đưa vào R. Vì vậy, R được khởi tạo thành {3, 5, 7}.
Sau đó, việc thực thi giảm xuống dưới UNION ALL và thành viên đệ quy được thực thi lần đầu tiên. Nó thực thi trên R (nghĩa là trên R mà chúng ta hiện có trong tay: {3, 5, 7}). Điều này dẫn đến {9, 25, 49}.
Nó làm gì với kết quả mới này? Nó có nối {9, 25, 49} vào {3, 5, 7} hiện tại, gắn nhãn kết quả R kết hợp, và sau đó tiếp tục với đệ quy từ đó không? Hoặc nó xác định lại R chỉ là kết quả mới này {9, 25, 49} và thực hiện tất cả các kết hợp sau?
Không có sự lựa chọn nào có ý nghĩa.
Nếu R bây giờ là {3, 5, 7, 9, 25, 49} và chúng tôi thực hiện lần lặp tiếp theo của phép đệ quy, thì chúng tôi sẽ kết thúc với {9, 25, 49, 81, 625, 2401} và chúng tôi mất {3, 5, 7}.
Nếu R bây giờ chỉ là {9, 25, 49}, thì chúng ta có vấn đề gắn nhãn sai. R được hiểu là sự kết hợp của tập kết quả thành viên neo và tất cả các tập kết quả thành viên đệ quy tiếp theo. Trong khi {9, 25, 49} chỉ là một thành phần của R. Nó không phải là R đầy đủ mà chúng tôi đã tích lũy cho đến nay. Do đó, để viết thành viên đệ quy như chọn từ R không có ý nghĩa gì.
Tôi chắc chắn đánh giá cao những gì @Max Vernon và @Michael S. đã nêu chi tiết dưới đây. Cụ thể, (1) tất cả các thành phần được tạo ra đến giới hạn đệ quy hoặc tập hợp null, và sau đó (2) tất cả các thành phần được liên kết với nhau. Đây là cách tôi hiểu đệ quy SQL để thực sự hoạt động.
Nếu chúng ta thiết kế lại SQL, có thể chúng ta sẽ thực thi một cú pháp rõ ràng và rõ ràng hơn, đại loại như thế này:
WITH R AS
(
SELECT N
INTO R[0]
FROM #NUMS
UNION ALL
SELECT N*N AS N
INTO R[K+1]
FROM R[K]
WHERE N*N < 10000000
)
SELECT N FROM R ORDER BY N;
Sắp xếp giống như một bằng chứng quy nạp trong toán học.
Vấn đề với đệ quy SQL như hiện tại là nó được viết theo một cách khó hiểu. Cách nó được viết nói rằng mỗi thành phần được hình thành bằng cách chọn từ R, nhưng điều đó không có nghĩa là toàn bộ R đã được (hoặc, dường như đã được) xây dựng cho đến nay. Nó chỉ có nghĩa là thành phần trước đó.