Toán tử SQL Logic Ưu tiên: Và và Hoặc


179

Là hai tuyên bố dưới đây tương đương?

SELECT [...]
FROM [...]
WHERE some_col in (1,2,3,4,5) AND some_other_expr

SELECT [...]
FROM [...]
WHERE some_col in (1,2,3) or some_col in (4,5) AND some_other_expr

Có một số loại bảng sự thật tôi có thể sử dụng để xác minh điều này?


4
Hãy thử: TT F. (T hoặc T) và F. T hoặc (T và F). Người đọc mã phải có thể thấy rõ ý định của người viết mã. Và người viết cần chắc chắn rằng cỗ máy đang làm những gì anh ta dự định. Dấu ngoặc đơn sắp xếp cả ba: người đọc, người viết và máy. :)
Assad Ebrahim

Câu trả lời:


290

Andđã được ưu tiên hơn Or, vì vậy, ngay cả khia <=> a1 Or a2

Where a And b 

không giống như

Where a1 Or a2 And b,

bởi vì điều đó sẽ được thực thi như

Where a1 Or (a2 And b)

và những gì bạn muốn, để làm cho chúng giống nhau, là như sau (sử dụng dấu ngoặc đơn để ghi đè các quy tắc ưu tiên):

 Where (a1 Or a2) And b

Đây là một ví dụ để minh họa:

Declare @x tinyInt = 1
Declare @y tinyInt = 0
Declare @z tinyInt = 0

Select Case When @x=1 OR @y=1 And @z=1 Then 'T' Else 'F' End -- outputs T
Select Case When (@x=1 OR @y=1) And @z=1 Then 'T' Else 'F' End -- outputs F

Đối với những người thích tham khảo tài liệu tham khảo (theo thứ tự chữ cái):


18
Đó là một thực hành tốt để sử dụng dấu ngoặc đơn ngay cả khi chúng không cần thiết. rất ít lập trình viên (nếu có) biết quyền ưu tiên của tất cả các toán tử có sẵn.
Trismegistos

1
@Trismegistos Ước gì nó không như vậy ... không nên như vậy, nhưng tôi đoán bạn đã đúng.
Charles Bretana

1
Điều này ANDsau đó ORlà một phần của tiêu chuẩn SQL?
Jaime Hablutzel

@Jaime, Có, và, afaik, nó cũng là một phần của tiêu chuẩn cho tất cả các ngôn ngữ lập trình.
Charles Bretana

4
@Bsienn, Không chắc chắn những gì bạn đã làm, nhưng điều đó không phù hợp với SQL tiêu chuẩn và với tài liệu MySQL ... dev.mysql.com/doc/refman/5.0/en/operator-precedence.html Bạn nên thử lại, - cẩn thận thời gian ... thử declare @x tinyInt = 1 declare @y tinyInt = 0 declare @z tinyInt = 0 select case when @x=1 or @y=1 and @z=1 then'T' else 'F' end select case when (@x=1 or @y=1) and @z=1 then'T' else 'F' end
Charles Bretana

33

Tôi sẽ thêm 2 điểm:

  • "IN" là các OR nối tiếp hiệu quả với dấu ngoặc đơn xung quanh chúng
  • VÀ được ưu tiên hơn OR trong mọi ngôn ngữ tôi biết

Vì vậy, 2 biểu thức đơn giản là không bằng nhau.

WHERE some_col in (1,2,3,4,5) AND some_other_expr
--to the optimiser is this
WHERE
     (
     some_col = 1 OR
     some_col = 2 OR 
     some_col = 3 OR 
     some_col = 4 OR 
     some_col = 5
     )
     AND
     some_other_expr

Vì vậy, khi bạn ngắt mệnh đề IN lên, bạn tách các OR nối tiếp lên và thay đổi quyền ưu tiên.


gbn Có sự kết hợp trong ORACLE SQL không? NẾU CÓ thì làm thế nào và ở đâu tôi có thể nhận được tất cả sự kết hợp của các nhà khai thác?
Asif Mushtaq

2
Nhiều như nó làm tôi đau đớn khi nói điều đó, VÀ không được ưu tiên hơn HOẶC trong ruby! Để làm cho mọi thứ tồi tệ hơn, && không được ưu tiên hơn ||! Một trong những lý do tôi không thích ruby ​​- nó vi phạm nguyên tắc ít gây ngạc nhiên nhất cho tôi. 2.2.1: 007> đúng hay đúng và sai => sai 2.2.1: 008> đúng | | đúng && sai => đúng
Alex L

23
  1. Toán tử số học
  2. Điều hành nối
  3. Điều kiện so sánh
  4. LÀ [KHÔNG] NULL, THÍCH, [KHÔNG] VÀO
  5. [KHÔNG PHẢI Ở GIỮA
  6. Không bằng
  7. KHÔNG điều kiện logic
  8. VÀ điều kiện logic
  9. HOẶC điều kiện logic

Bạn có thể sử dụng dấu ngoặc đơn để ghi đè các quy tắc ưu tiên.


9

Truy vấn để hiển thị bảng chân lý biểu thức boolean 3 biến:

;WITH cteData AS
(SELECT 0 AS A, 0 AS B, 0 AS C
UNION ALL SELECT 0,0,1
UNION ALL SELECT 0,1,0
UNION ALL SELECT 0,1,1
UNION ALL SELECT 1,0,0
UNION ALL SELECT 1,0,1
UNION ALL SELECT 1,1,0
UNION ALL SELECT 1,1,1
)
SELECT cteData.*,
    CASE WHEN

(A=1) OR (B=1) AND (C=1)

    THEN 'True' ELSE 'False' END AS Result
FROM cteData

Kết quả cho (A=1) OR (B=1) AND (C=1):

A   B   C   Result
0   0   0   False
0   0   1   False
0   1   0   False
0   1   1   True
1   0   0   True
1   0   1   True
1   1   0   True
1   1   1   True

Kết quả cho (A=1) OR ( (B=1) AND (C=1) )giống nhau.

Kết quả cho ( (A=1) OR (B=1) ) AND (C=1):

A   B   C   Result
0   0   0   False
0   0   1   False
0   1   0   False
0   1   1   True
1   0   0   False
1   0   1   True
1   1   0   False
1   1   1   True
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.