Bí danh của truy vấn con giống như bí danh của truy vấn chính


22

Tôi có một truy vấn SQL có bí danh giống như một số bí danh của truy vấn con.

Ví dụ:

select *
from ROOM r
where ...
         (
              select *
              from ROAD r
              where ...
         )

Điều này hoạt động tốt, vì bí danh của truy vấn phụ dường như che giấu chính.

  1. Nó sẽ hoạt động theo cách đó trong mọi trường hợp?
  2. Tôi sẽ bao giờ nhận được kết quả không xác định?
  3. Nếu nó ổn để làm điều đó, làm thế nào tôi có thể tham chiếu đến truy vấn chính r?

1
Câu trả lời ngắn gọn là "1. Có", "2.Không" và "3. trong trường hợp đó, bạn không thể (vì vậy sẽ không thực sự ổn nếu bạn muốn đưa ra một tài liệu tham khảo như vậy)"
ypercubeᵀᴹ

Câu trả lời:


15

Các truy vấn con lồng nhau có thể sử dụng cùng các bí danh như được sử dụng trong truy vấn cha, mặc dù có thể hơi khó hiểu khi ai đó đọc mã. Không gian tên cho các bí danh trên một truy vấn con lồng nhau tách biệt với không gian tên trên cha mẹ. Ví dụ: truy vấn bên dưới có một truy vấn con lồng nhau bcũng có một bí danh bđược sử dụng trong nó. Điều này có thể gây nhầm lẫn cho lập trình viên nhưng tốt với công cụ DBMS:

   select a.foo
          ,b.bar
          ,b.BarCount
      from (select b.bar
                  ,count (*) as BarCount
              from BarTable b
              join OtherTable o
                on b.OtherTableID = o.OtherTableID
             group by b.bar) b
      join Foobar a
        on a.bar = b.bar

Trên truy vấn con tương quan, bạn có quyền truy cập vào các bí danh của cha mẹ, vì vậy các bí danh phải là duy nhất trong truy vấn cha và truy vấn con tương quan. Nếu chúng ta có một truy vấn con tương quan, chẳng hạn như bên dưới, chúng ta có một không gian tên toàn cục duy nhất được chia sẻ giữa truy vấn cha và truy vấn con tương quan:

select a.foo
      ,b.bar
  from Foobar a
  join Bar b
    on b.FooBarID = a.FooBarID
 where not exists
       (select 1
          from Bar b2
         where b2.BarCategoryID = b.BarCategoryID
           and b2.BarDate > b.BarDate)

Subquery tương quan không có một bí danh vì nó không tham gia vào một tham gia như vậy 1 . Các tham chiếu bb2for barđều có sẵn cho truy vấn con khi các truy vấn con tương quan chia sẻ không gian tên của chúng cho các bí danh với cha mẹ.


1 Lưu ý rằng trình tối ưu hóa có thể chọn sử dụng các toán tử nối trong kế hoạch phía sau hậu trường, mặc dù thao tác thực tế được chỉ định là truy vấn con tương quan và không phải là nối với truy vấn con lồng nhau.


Truy vấn con trong truy vấn đầu tiên là một bảng dẫn xuất và SQL tiêu chuẩn yêu cầu nó luôn phải được đặt tên: không có lý do logic nào cho yêu cầu này nhưng SQL Server vẫn triển khai nó, mặc dù trong ví dụ cụ thể bạn đã chọn một tên thực sự cần thiết. Truy vấn con trong truy vấn thứ hai không phải là bảng dẫn xuất, do đó tại sao nó không yêu cầu tên (thực tế nó là truy vấn con tương quan là không quan trọng).
onedaywhen

@encedaywhen - Tôi không thể nghĩ đến bất kỳ tình huống nào ngoài một truy vấn con tương quan trong đó truy vấn phụ cần truy cập vào các bí danh được sử dụng trong cha mẹ. Bạn đã có một cái gì đó cụ thể trong tâm trí?
Mối quan tâmOfTunbridgeWells

Tôi không chắc là tôi hiểu câu hỏi của bạn. Có lẽ tôi nên nói rõ rằng tôi đã trả lời cụ thể cho nhận xét của bạn, "Truy vấn con tương quan không có bí danh vì nó không tham gia vào một tham gia như vậy." Phản hồi của tôi được cho là truyền đạt điểm rằng các quy tắc liên quan đến các biến phạm vi (cái mà tiêu chuẩn SQL gọi là 'tên tương quan' và bạn gọi là 'bí danh') không liên quan trực tiếp đến sự tham gia của chúng (hoặc nói cách khác) trong các phép nối.
onedaywhen

Ví dụ đơn giản: SELECT * FROM ( SELECT c FROM T ) AS T2;- không tham gia, không có tương quan nào nhưng tiêu chuẩn SQL yêu cầu bảng dẫn xuất được gán một biến phạm vi ( T2trong trường hợp này).
onedaywhen

3

ConcernedOfTunbridgeWells, bạn viết (nhấn mạnh của tôi): "Trên một truy vấn con tương quan, bạn có quyền truy cập vào các bí danh của cha mẹ, vì vậy các bí danh phải là duy nhất trong truy vấn cha và truy vấn phụ tương quan."

Tôi không tin sự độc đáo là bắt buộc. Tôi tin rằng, nếu một bí danh được sử dụng trong truy vấn con tương quan làm tên tương quan, cũng như bí danh bảng trong truy vấn bên ngoài, bí danh trong truy vấn phụ sẽ được ưu tiên.

Thí dụ:

CREATE TABLE #T (A INT)
CREATE TABLE #U (A INT)
CREATE TABLE #V (A INT)

INSERT INTO #T (A) VALUES (1), (2), (3)
INSERT INTO #U (A) VALUES (2), (3), (4)
INSERT INTO #V (A) VALUES (3), (4), (5)

SELECT
    T1.A
FROM
    #T AS T1
    INNER JOIN #U AS T2 ON T1.A = T2.A
WHERE
    EXISTS (SELECT * FROM #V AS T2 WHERE T1.A = T2.A)

Đầu ra là "3": các bảng T và U có 2 và 3 điểm chung, nhưng biến WHEREvị ngữ tiếp tục lọc các hàng được trả về 3 và 2 không tồn tại trong V.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.