2012-07-31 49 views
16

Tôi đang cố gắng tìm hiểu SQL, sử dụng PostgreSQL 9.1.3. Tôi muốn hiểu một số hành vi khiến tôi bị mâu thuẫn. Để wit:PostgreSQL lồng nhau CTE và UNION

này hoạt động:

WITH innermost AS (SELECT 2) 
SELECT * FROM innermost 
UNION SELECT 3; 

tôi có được điều này:

?column? 
---------- 
     2 
     3 

này hoạt động:

WITH outmost AS (
     (WITH innermost AS (SELECT 2) 
     SELECT * FROM innermost) 
)         
SELECT * FROM outmost; 

Kết quả:

?column? 
---------- 
     2 

này cũng hoạt động:

WITH outmost AS (
    SELECT 1 
    UNION (WITH innermost AS (SELECT 2) 
     SELECT * FROM innermost) 
) 
SELECT * FROM outmost; 

tôi có được điều này:

?column? 
---------- 
     1 
     2 

Nhưng điều này không không công việc:

WITH outmost AS (
    SELECT 1 
    UNION (WITH innermost as (SELECT 2) 
     SELECT * FROM innermost 
     UNION SELECT 3) 
) 
SELECT * FROM outmost; 

Kết quả:

ERROR: relation "innermost" does not exist 
LINE 4:   SELECT * FROM innermost 

Theo cách suy nghĩ của tôi, người cuối cùng nên thành công hoặc một trong những người khác sẽ thất bại. Tôi không thấy mẫu. Có một số quy tắc chung nào có thể cho phép tôi dự đoán sự kết hợp của CTE lồng ghép và UNIONs nào sẽ hoặc sẽ không hoạt động?

+0

Mặc dù truy vấn cuối cùng của bạn trông có vẻ khó xử, nó phải là Ok, IMHO. Nó có thể là một lỗi ưu tiên/kết hợp trong trình phân tích cú pháp. Có một số hạn chế ngữ nghĩa (Không có CTE đệ quy lồng nhau, IIRC); có thể trình phân tích cú pháp quá cầu kỳ, hoặc quá kích hoạt. Cá nhân, tôi sử dụng rất nhiều CTE lồng nhau (lên đến 4 cấp độ sâu), nhưng tôi hiếm khi sử dụng UNION, ngoại trừ trong CTE đệ quy. – wildplasser

+2

@AdamMackler bạn nên đặt câu trả lời cho câu hỏi của riêng bạn – araqnid

+3

Tom Lane thừa nhận bạn đã tìm thấy lỗi, giống như một sự chấp thuận chính thức mà bạn đã hỏi một câu hỏi rất hay. Vui lòng đăng nội dung bạn nhận được từ danh sách dưới dạng câu trả lời và đảm bảo thêm liên kết vào chuỗi. –

Trả lời

17

Bí ẩn được giải quyết: hành vi mà tôi quan sát là lỗi đã biết. Tôi gửi các bài bản gốc cùng với một danh sách PostgreSQL cụ thể và nhận được câu trả lời này:.

Đây là một lỗi :-(Mã phân tích phân tích dường như nghĩ rằng VỚI chỉ có thể được gắn vào cấp cao nhất hoặc một lá cấp SELECT trong một cây hoạt động thiết lập , nhưng ngữ pháp tuân theo tiêu chuẩn SQL mà nói không có điều đó. sau đó nó hoàn toàn bị bỏ qua trong quá trình phân tích phân tích cú pháp. Sẽ thấy khoảng sửa lỗi.

 regards, tom lane 

http://archives.postgresql.org/pgsql-novice/2012-07/msg00113.php

+3

Có vẻ như điều này đã được sửa trong 9.2 beta3. Tôi trích dẫn các bản tin: '* Fix WITH vấn đề với các hoạt động thiết lập (UNION/INTERSECT/EXCEPT)'. –

+2

Tôi vừa cài đặt 9.2beta3 và có, lệnh không hoạt động trong bài đăng gốc của tôi hiện hoạt động như mong đợi. Cảm ơn bạn cho người đứng đầu lên. –

+0

Tuyệt! Cảm ơn bạn đã theo dõi điều này! Câu hỏi của bạn xứng đáng có nhiều upvotes hơn. :) BTW, nó được khuyến khích để chấp nhận câu trả lời (chính xác) của riêng bạn trong trường hợp như vậy. –