2010-09-14 31 views
5

tôi cần phải truy vấn dữ liệu từ một bảng thứ hai, nhưng chỉ khi nào một tập hiếm hoi của điều kiện trong bảng chính được đáp ứng:MySQL Short Circuit có phải là hàm IF() không?

SELECT ..., IF(a AND b AND c AND (SELECT 1 FROM tableb ...)) FROM tablea ... 

a, b, và điều kiện c là hầu như luôn luôn sai lầm, vì vậy suy nghĩ của tôi là truy vấn phụ sẽ không bao giờ thực hiện cho hầu hết các hàng trong tập kết quả và do đó sẽ nhanh hơn so với kết nối. Nhưng điều đó sẽ chỉ đúng nếu câu lệnh IF() ngắn mạch.

Có phải không?

Cảm ơn sự giúp đỡ nào mà các bạn có thể cung cấp.

Trả lời

2

Với sự trợ giúp của J. Jorgenson Tôi đã đưa ra trường hợp thử nghiệm của riêng mình. Ví dụ của ông không cố gắng để ngắn mạch trong việc đánh giá điều kiện, nhưng sử dụng ý tưởng của mình tôi đã đưa ra kiểm tra của riêng tôi và xác minh rằng MySQL thực sự ngắn mạch kiểm tra điều kiện IF().

SET @var:=5; 
SELECT IF(1 = 0 AND (@var:=10), 123, @var); #Expected output: 5 
SELECT IF(1 = 1 AND (@var:=10), @var, 123); #Expected output: 10 

Trên ví dụ thứ hai, MySQL là đúng cách ngắn mạch: @var không bao giờ được thiết lập để 10

Thanks for the help J. Jorgenson!

0

Hãy thử trong trình phân tích SQL. Nếu bạn muốn ở bên an toàn và không phải tin tưởng cơ sở dữ liệu để làm việc theo một cách (và không thay đổi hành vi đó trong các phiên bản mới), chỉ cần thực hiện hai truy vấn và thực hiện lập trình IF.

8

Câu trả lời là CÓ.
IF (cond, expr_true, expr_false) trong một truy vấn mysql ngắn mạch.

Dưới đây là một thử nghiệm, sử dụng @variables để chứng minh một thực tế:

SET @var:=5; 
SELECT IF(1 = 0, (@var:[email protected] + 1), @var); -- using ':=' operator to modify 'true' expr @var 
SELECT IF(1 = 1, @var, (@var:[email protected] + 1)); -- using ':=' operator to modify 'false' expr @var 
SELECT @var; 

Kết quả là '5' từ cả ba truy vấn SELECT.

Hàm IF() KHÔNG được đoản mạch, kết quả sẽ là '5' từ SELECT # 1 và '6' từ SELECT # 2 và '7' từ "select @var" cuối cùng.

Điều này là do biểu thức 'đúng' KHÔNG BAO GIỜ được thực hiện, trong lựa chọn # 1 và cũng không phải là biểu thức sai được thực hiện cho lựa chọn # 2.

Lưu ý toán tử ': =' được sử dụng để sửa đổi @var, trong một truy vấn SQL (chọn, từ, và ở đâu mệnh đề). Bạn có thể nhận được một số SQL thực sự ưa thích/phức tạp từ này. Tôi đã sử dụng @vars để áp dụng logic 'thủ tục' trong một truy vấn SQL.

- J Jorgenson -

0

Điều đó tùy thuộc.

NẾU không ngắn mạch như vậy mà nó có thể được sử dụng để tránh cảnh báo cắt ngắn với GROUP_CONCAT, ví dụ như trong:

set @@group_concat_max_len = 5; 

select if(true or @var:=group_concat('warns if evaluated'), 'actual result', @var); 

kết quả sẽ là 'kết quả thực tế' nhưng bạn sẽ nhận được một cảnh báo :

Warning (Code 1260): Row 1 was cut by GROUP_CONCAT() 

cảnh báo tương tự bạn nhận được với biểu thức GROUP_CONCAT ít quan trọng hơn, chẳng hạn như khóa riêng biệt và không có NẾU.

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