SQL Operator Precedence
AND binds tighter than OR — mixing them without parentheses can silently produce the wrong rows.
What & Why
When AND and OR appear in the same condition, Postgres evaluates AND first — exactly like multiplication binds tighter than addition in arithmetic. Without parentheses, the query might not mean what it looks like it means.
See How It Works
| id | name | channel | spend | start_date | end_date | status | target_segment |
|---|---|---|---|---|---|---|---|
| 1 | Spring Launch | google_ads | 55000.00 | 2024-01-15 | 2024-03-31 | active | smb |
| 2 | Retention Webinar | 45000.00 | 2024-02-10 | 2024-04-15 | active | enterprise | |
| 3 | Finance Retargeting | 50000.00 | 2024-03-12 | 2024-05-31 | active | enterprise | |
| 4 | Enterprise Search | google_ads | 60000.00 | 2024-04-01 | 2024-06-30 | active | enterprise |
EXAMPLE QUERY
SELECT name FROM marketing.campaigns
WHERE channel = 'linkedin' OR channel = 'email' AND spend > 55000;ACTUAL RESULT — AND is evaluated first
| name |
|---|
| Finance Retargeting |
SQL evaluates `channel = 'linkedin' OR (channel = 'email' AND spend > 55000)`, so Finance Retargeting survives. The mistaken grouping `(linkedin OR email) AND spend > 55000` would return no rows.
Now You Try
Practice this concept
Marketing wants active email campaigns plus every webinar campaign, regardless of status. Apply SQL logical precedence correctly.
Available schema
marketingPrefix tables with marketing.table_name.
namechannelstatusmarketing.campaigns| Column | Type |
|---|---|
| id | integer |
| name | text |
| channel | text |
| spend | numeric |
| start_date | date |
| end_date | date |
| status | text |
| target_segment | text |
| legacy_id | text |
query.sql
Sign up free to try it on a real business scenario