Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How exactly does using OR in a MySQL statement differ with/without parentheses?

Tags:

sql

mysql

I have this query:

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02' 
    AND `status` = 'active' OR `status` = 'past due'

Which does not return the correct results. However, adding parentheses around the OR conditions makes it work like so:

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02'
    AND (`status` = 'active' OR `status` = 'past due')

My question is why is it different? I understand that's is considering the OR statement differently without the parentheses; but I don't understand how it's different.

I haven't found any docs that have been helpful on this. If there's any links out there I'd really appreciate it.

like image 534
drewjoh Avatar asked Feb 02 '11 08:02

drewjoh


People also ask

Do parentheses matter in SQL?

Parentheses tell SQL Server to ignore the order of evaluation and assess what is in the parentheses first then evaluate the second part of the WHERE clause. Using sql and or queries without parentheses gives incorrect record.

What is the purpose to use like a clause in MySQL?

The LIKE operator is used in a WHERE clause to search for a specified pattern in a column. There are two wildcards often used in conjunction with the LIKE operator: The percent sign (%) represents zero, one, or multiple characters.

What this symbol <> means in MySQL?

The symbol <> in MySQL is same as not equal to operator (!=). Both gives the result in boolean or tinyint(1). If the condition becomes true, then the result will be 1 otherwise 0. Case 1 − Using !=

What do brackets mean in MySQL?

The brackets are required if you use keywords or special chars in the column or database names. Also square brackets are the way to use a reserved word as a field name (for instance [date])


2 Answers

This is because OR has lower operator precedence than AND. Whenever the DB sees an expression like

A AND B OR C

the AND is evaluated first, i.e. it is equivalent to

(A AND B) OR C

So if you explicitly want

A AND (B OR C)

instead, you must put in the parentheses.

This is btw not specific to SQL. The order of precedence of these operators is the same in all programming languages I know (i.e. at least C, C++, C#, Java and Unix shell scripts).

like image 141
Péter Török Avatar answered Sep 21 '22 19:09

Péter Török


SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02' 
AND `status` = 'active' OR `status` = 'past due'

In this example, you will get all records where either

a) The date_next_payment is before 2nd Feb 2011 AND status is active

b) The status is past_due

So the past_due records will not be restricted by date.

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02'
AND (`status` = 'active' OR `status` = 'past due')

In this example, you will get all records where

a) The date_next_payment is before 2nd Feb 2011

AND

b) The status is either active or past_due

The brackets work like they do in maths or logic - the statements inside the brackets get evaluated first... so imagine seeing each step take place like this:

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02'
AND (`status` = 'active' OR `status` = 'past due')

So a record is encountered with a status of active...

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02'
AND (TRUE OR FALSE)

This then evaluates, with the OR condition... (TRUE OR FALSE) == TRUE

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02'
AND TRUE

And the date is 2011-01-01

SELECT * FROM (`users`) WHERE TRUE
AND TRUE

And finally, TRUE AND TRUE == TRUE

SELECT * FROM (`users`) WHERE TRUE

And so the record is returned...

Imagining your query being executed in steps like this against each row in the database sometimes helps to understand where to put your brackets.

like image 44
Fenton Avatar answered Sep 21 '22 19:09

Fenton