2010-06-16 18 views
13

Có cách nào để cho một subquery trong Oracle 11g một bí danh như:Có cách nào để cung cấp cho một truy vấn phụ một bí danh trong Oracle 11g SQL?

select * 
from 
    (select client_ref_id, request from some_table where message_type = 1) abc, 
    (select client_ref_id, response from some_table where message_type = 2) defg 
where 
    abc.client_ref_id = def.client_ref_id; 

Nếu không có cách nào để tham gia hai truy vấn phụ dựa trên client_ref_id. Tôi nhận ra có một tham gia tự, nhưng trên cơ sở dữ liệu tôi chạy trên tự tham gia có thể mất đến 5 phút để hoàn thành (có một số logic phụ trong truy vấn thực tế tôi đang chạy nhưng tôi đã xác định tham gia tự là gây ra vấn đề). Các truy vấn phụ riêng lẻ chỉ mất vài giây để hoàn thành bởi bản thân chúng. Truy vấn tự tham gia trông giống như sau:

select st.request, st1.request 
from 
    some_table st, some_table st1 
where 
    st.client_ref_id = st1.client_ref_id; 
+0

Chỉ tò mò, câu trả lời được chấp nhận có hiệu quả như thế nào? – DCookie

+1

Bạn đã không tìm ra đó là tự tham gia. Tạo một bản sao giống hệt nhau của bảng, chỉ mục và thống kê và xem bạn có nhận được cùng một thời điểm hay không. Câu hỏi hay hơn sẽ là, "Giúp tôi điều chỉnh truy vấn này" và đăng truy vấn ĐẦY ĐỦ, và kế hoạch giải thích. –

Trả lời

16
 
WITH abc as (select client_ref_id, request from some_table where message_type = 1) 
select * 
from abc 
    inner join 
    (select client_ref_id, response from some_table where message_type = 2) defg 
on abc.client_ref_id = def.client_ref_id; 
+0

Thuật ngữ kỹ thuật cho phần "WITH abc as (select ...)" là gì? Nếu muốn nghiên cứu về khả năng của nó. – SeaBass

+2

@SeaBass: Biểu thức bảng chung, thường được viết tắt là CTE (cũng thường được sử dụng làm tên/bí danh, mặc dù tôi không làm như vậy lần này). Lưu ý rằng cả hai "bảng" có thể đã được thực hiện như một phần của CTE, tôi chỉ muốn hiển thị cả hai tùy chọn, do đó, đã làm một cách này và cách khác, một khác. – jmoreno

5

Tôi không có cá thể Oracle để kiểm tra, nhưng những gì bạn đăng phải là cú pháp ANSI-89 JOIN hợp lệ. Dưới đây là trong ANSI-92:

SELECT * 
    FROM (SELECT client_ref_id, request 
      FROM SOME_TABLE 
     WHERE message_type = 1) abc 
    JOIN (SELECT client_ref_id, request 
      FROM SOME_TABLE 
     WHERE message_type = 1) defg ON defg.client_ref_id = abc.client_ref_id 
3

Truy vấn của bạn sẽ ổn.

Một thay thế sẽ là:

select abc.client_ref_id, abc.request, def.response 
from some_table abc, 
     some_table def 
where abc.client_ref_id = def.client_ref_id 
and abc.message_type = 1 
and def.message_type = 2; 

Tôi sẽ không ngạc nhiên nếu Oracle viết lại các truy vấn để kế hoạch này sẽ được như vậy anyway.

+0

Giải pháp này là những gì mất quá nhiều thời gian để hoàn thành trên cơ sở dữ liệu tôi đang sử dụng. Câu lệnh 'abc.client_ref_id = def.client_ref_id' khiến truy vấn chuyển từ vài giây để mất hơn một giờ để hoàn thành. –

+0

Bạn phải rất cẩn thận về thời gian. Bạn đang nói về thời gian hàng cuối cùng? hoặc chỉ là hàng đầu tiên? Một số kế hoạch truy vấn có thể tạo ra 1 hàng rất nhanh (một giây) nhưng sẽ mất một năm để tạo ra hàng cuối cùng. Trong khi những người khác sẽ nhận được hàng cuối cùng trong một phút. –

+0

@Matt, đăng kế hoạch truy vấn - không có gì thú vị với SQL khi chúng tôi không biết nguyên nhân gây ra vấn đề hiệu suất. –

Các vấn đề liên quan