Diutamakan Operator Logika SQL: Dan dan Atau

179

Apakah kedua pernyataan di bawah ini setara?

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

dan

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

Apakah ada semacam tabel kebenaran yang bisa saya gunakan untuk memverifikasi ini?

nc.
sumber
4
Coba: TT F. (T atau T) dan F. T atau (T dan F). Pembaca kode harus jelas dapat melihat maksud dari penulis kode. Dan penulis perlu memastikan bahwa mesin itu melakukan apa yang dia maksudkan. Kurung menyelaraskan ketiganya: pembaca, penulis, dan mesin. :)
Assad Ebrahim

Jawaban:

290

Andtelah didahulukan Or, jadi, bahkan jikaa <=> a1 Or a2

Where a And b 

tidak sama dengan

Where a1 Or a2 And b,

karena itu akan Dieksekusi sebagai

Where a1 Or (a2 And b)

dan apa yang Anda inginkan, untuk membuatnya sama, adalah sebagai berikut (menggunakan tanda kurung untuk mengesampingkan aturan prioritas):

 Where (a1 Or a2) And b

Berikut ini contoh untuk diilustrasikan:

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

Bagi mereka yang suka berkonsultasi referensi (dalam urutan abjad):

Charles Bretana
sumber
18
Merupakan praktik yang baik untuk menggunakan tanda kurung meskipun tidak dibutuhkan. sangat sedikit pemrogram (jika ada) yang tahu diutamakan dari semua operator yang tersedia.
Trismegistos
1
@ Trismegistos Berharap tidak begitu ... tidak seharusnya begitu, tapi saya kira Anda benar.
Charles Bretana
1
Ini ANDkemudian ORdiutamakan adalah bagian dari standar SQL?
Jaime Hablutzel
@Jaime, Ya, dan, afaik, ini juga merupakan bagian dari standar untuk semua bahasa pemrograman.
Charles Bretana
4
@Bsienn, Tidak yakin apa yang Anda lakukan, tapi itu tidak konsisten dengan SQL standar dan dengan dokumentasi MySQL ... dev.mysql.com/doc/refman/5.0/id/operator-precedence.html Anda harus mencoba lagi, - dengan hati-hati ini waktu ... coba 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

Saya akan menambahkan 2 poin:

  • "IN" secara efektif OR seri dengan tanda kurung di sekitar mereka
  • DAN memiliki prioritas di atas ATAU dalam setiap bahasa yang saya tahu

Jadi, 2 ekspresi sama sekali tidak sama.

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

Jadi, ketika Anda memecahkan klausa IN, Anda membagi OR seri ke atas, dan mengubah prioritas.

gbn
sumber
gbn Apakah ada asosiatif dalam ORACLE SQL? JIKA YA lalu bagaimana dan di mana saya bisa mendapatkan semua operator asosiasi?
Asif Mushtaq
2
Sebanyak apapun menyakitkan saya untuk mengatakannya, DAN tidak memiliki prioritas di atas ATAU dalam ruby! Lebih buruk lagi, && memang memiliki prioritas lebih dari ||! Salah satu alasan mengapa saya tidak suka ruby ​​- itu melanggar prinsip ketakjuban yang paling rendah bagi saya. 2.2.1: 007> benar atau benar dan salah => salah 2.2.1: 008> true || true && false => true
Alex L
23
  1. Operator aritmatika
  2. Operator gabungan
  3. Kondisi perbandingan
  4. IS [NOT] NULL, LIKE, [NOT] IN
  5. [TIDAK DIANTARA
  6. Tidak sebanding dengan
  7. BUKAN kondisi logis
  8. DAN kondisi logis
  9. ATAU kondisi logis

Anda bisa menggunakan tanda kurung untuk mengesampingkan aturan prioritas.

Yassine Abdul-Rahman
sumber
9

Kueri untuk menampilkan tabel kebenaran ekspresi boolean 3-variabel:

;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

Hasil untuk (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

Hasil untuk (A=1) OR ( (B=1) AND (C=1) )adalah sama.

Hasil untuk ( (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
Ajs Jsy
sumber