Kiểm tra xem có bất kỳ giá trị nào trong kết quả truy vấn con không


8

Tôi có một truy vấn con phức tạp trả về danh sách ID đơn hàng. Tôi cần có được một danh sách khách hàng có những đơn hàng này. Vấn đề là có hai cách gán khách hàng cho một đơn hàng (một trong hai lĩnh vực). Tôi chỉ có thể làm những thứ như thế này:

 select *
 from Customers
 where orderId in (select...) 
 or secondaryOrderId in (select ...)

Vấn đề là truy vấn con là rất lớn, cả về thời gian cần thiết để thực hiện và trong không gian màn hình. Có cách nào để kiểm tra xem một trong các trường có chứa một trong các kết quả mong muốn không?

Câu trả lời:


10

Thử:

where exists (select * .... 
        where Customers.orderId = ... 
        or Customers.secondaryId = ...
     )

Ví dụ: nếu bạn đang lên kế hoạch:

where orderId in (select value from ...)
or secondaryorderid in (select value from ...)

Sau đó, bạn thực hiện nó để bạn chỉ gọi truy vấn con của bạn một lần và xây dựng mệnh đề OR của bạn vào đó.

 where exists (select * from ... 
        where Customers.orderId = value 
        or Customers.secondaryOrderId = value
     )

Toàn bộ vấn đề này là để đảm bảo rằng truy vấn con phức tạp chỉ được thực hiện một lần. Điều đó không xảy ra với CTE hoặc bằng cách thay thế hai IN bằng hai EXISTS.


3

Bạn có thể nên viết lại truy vấn existsthay vì mộtin

Xem liên kết này để biết thêm ví dụ.

Truy vấn của bạn sau đó sẽ tìm kiếm một cái gì đó dọc theo dòng

select *
from Customers C
where exists (select 'x' from ordertable o where c.orderid = o.orderid) 
or exists (select 'x' from ordertable o where c.secondaryOrderId = o.orderid) 

Nếu cả hai truy vấn con giống nhau, bạn có thể xóa một trong số chúng và kết hợp chúng như vậy

select *
from Customers C
where exists (select 'x' from ordertable o where c.orderid = o.orderid or c.secondaryOrderId = o.orderid) 

2

Tại sao không sử dụng withmệnh đề aka Bảng biểu thức chung ? Nó được thiết kế cho chính xác mục đích này (trong số những người khác).

with orderIds as (
  select orderId
  from ...
)
select *
from Customers
where orderId in (select orderId from orderIds) 
or secondaryOrderId in (select orderId from orderIds);

Xem https://msdn.microsoft.com/en-us/l Library / ms175972% 28v = sql.105% 29.aspx để biết tài liệu của Microsoft.


3
Không thực sự nhiều lợi ích bằng cách làm điều này về thời gian thực hiện. CTE không được lưu trong bộ nhớ cache và sẽ được thực thi cả hai lần nó được tham chiếu. stackoverflow.com/questions/22041244/
Mark Sinkinson

1
ĐỒNG Ý. Có vẻ mỗi DBMS xử lý CTE khác nhau.
Colin 't Hart

Một CTE không được thiết kế cho mục đích này. Nó vẫn sẽ được mở rộng thành truy vấn chính hai lần. Hãy thử và xem ...
Rob Farley

1
Và tài liệu của Microsoft là sai lệch "[CTE] có thể được coi là tập kết quả tạm thời" mà tôi hiểu là kết quả được lưu trong bộ nhớ cache hoặc được lưu trữ như bảng tạm thời. Bây giờ có một giải pháp T-SQL khác chưa được đề cập.
Colin 't Hart

@ Colin'tHart Chào mừng bạn đến với thế giới tài liệu của Microsoft :-)
Mark Sinkinson
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.