Chapter 17: PostgreSQL Operators
PostgreSQL: Operators βπ§
When people say βPostgreSQL operatorsβ, they usually mean all the special symbols and short keywords that you put between values to compare them, combine them, do math with them, check membership, work with JSON, do pattern matching, do bitwise operations, etc.
PostgreSQL has way more operators than most other databases β and many of them are very expressive and unique.
1. Quick classification β the families of operators youβll meet every day
| Category | Most important operators | Typical feeling / use case | PostgreSQL strength level |
|---|---|---|---|
| Arithmetic | + – * / % ^ |/ @ | Money calculations, age computation | β β β ββ |
| Comparison | = <> != < > <= >= IS [NOT] NULL | Filtering rows | β β β β β |
| Logical | AND OR NOT | Combining conditions | β β β β β |
| String / Pattern matching | | LIKE ILIKE ~ ~* SIMILAR TO | Search, validation | β β β β β |
| JSON/JSONB | -> ->> #> #>> @> <@ ? ?& ?| @? @@ | Modern app data, API responses | β β β β β β (best in class) |
| Array | && <@ @> = && | & | Tags, permissions, multivalue columns | β β β β β |
| Fuzzy / Similarity | % <-> <@> <% (with pg_trgm extension) | Search-as-you-type, typo-tolerant search | β β β β β |
| Bitwise | & | # ~ << >> | Flags, permissions, low-level bit manipulation | β β β ββ |
| Geometric / Geometric ops | && <-> @> <@ << >> &< &> | GIS, bounding boxes (with PostGIS even more) | β β β β β |
| Text search | @@ @@@ <-> (with tsvector / tsquery) | Full-text search | β β β β β |
| Containment / Overlap | @> <@ && (used in many types: jsonb, array, range, gist indexesβ¦) | βcontainsβ, βoverlapsβ checks | β β β β β |
2. Most frequently used operators β with real examples (our bookstore_demo style)
Letβs assume we have the books and customers tables from our previous demo database.
Arithmetic & Math operators
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
-- Price with 18% GST SELECT title, price, price * 1.18 AS price_with_gst FROM books; -- Integer division & remainder SELECT stock_quantity / 10 AS full_boxes, stock_quantity % 10 AS loose_books FROM books; -- Square root (useful in statistics sometimes) SELECT title, |/ stock_quantity AS approx_sqrt_stock FROM books; |
Comparison & IS / IS NOT
|
0 1 2 3 4 5 6 7 8 9 10 11 |
SELECT title, price FROM books WHERE price BETWEEN 200 AND 400 -- inclusive AND publication_year >= 2000 AND stock_quantity IS NOT NULL AND stock_quantity > 0; |
Logical operators (AND / OR / NOT)
|
0 1 2 3 4 5 6 7 8 9 10 |
SELECT title, price, stock_quantity FROM books WHERE (price < 300 OR publication_year > 2015) AND NOT (stock_quantity = 0) AND is_available = TRUE; |
String concatenation & LIKE / ILIKE
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
-- Concatenation (|| is standard, + does NOT work in PostgreSQL) SELECT first_name || ' ' || last_name || ' <' || email || '>' AS contact_info FROM customers; -- Case-insensitive search (ILIKE = very common in India) SELECT title FROM books WHERE title ILIKE '%harry potter%' OR title ILIKE '%small things%'; |
Regular expressions (~ ~* !~ !~*)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
-- Find titles that start with "The " and have space after SELECT title FROM books WHERE title ~ '^The\s'; -- ^ = start, \s = whitespace -- Case-insensitive regex SELECT email FROM customers WHERE email ~* 'gmail\.com$'; -- ends with gmail.com |
JSONB operators β PostgreSQLβs superpower in 2026
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
-- Assume we add a details JSONB column to books later SELECT title, details->>'publisher' AS publisher FROM books WHERE details @> '{"publisher": "Penguin"}'; -- contains this key-value -- Get value as text SELECT title, details->>'language' AS lang FROM books; -- Check if key exists SELECT title FROM books WHERE details ? 'awards'; -- has "awards" key -- Check multiple keys exist SELECT title FROM books WHERE details ?& ARRAY['isbn13', 'edition']; |
Array operators (very useful for tags, roles, etc.)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
-- Assume we add column tags TEXT[] to books SELECT title FROM books WHERE tags && ARRAY['fiction', 'indian']; -- overlaps / shares at least one SELECT title FROM books WHERE tags @> ARRAY['mythology']; -- contains all these tags SELECT title FROM books WHERE 'classics' = ANY(tags); -- contains this single value |
Containment & Overlap (works on jsonb, arrays, ranges, geometryβ¦)
|
0 1 2 3 4 5 6 7 8 9 10 |
-- JSONB containment WHERE details @> '{"category": "fantasy", "age_group": "teen"}'::jsonb -- Range containment (if we had price_range column) WHERE price_range @> 350::numeric -- 350 is inside the range |
Full-text search operators (basic example)
|
0 1 2 3 4 5 6 7 8 |
SELECT title FROM books WHERE to_tsvector('english', title || ' ' || description) @@ to_tsquery('english', 'potter & stone'); |
3. Quick reference table β top 30 operators beginners should know by heart
| Operator | Meaning | Example | Returns |
|---|---|---|---|
| = | Equals | price = 399 | boolean |
| <> / != | Not equals | status <> ‘cancelled’ | boolean |
| LIKE / ILIKE | Pattern match (% _) | title ILIKE ‘%harry%’ | boolean |
| ~ / ~* | Regex match / case-insensitive | email ~* ‘gmail.com$’ | boolean |
| && | Array overlap / jsonb key overlap | tags && ARRAY[‘sci-fi’] | boolean |
| @> | Contains | details @> ‘{“in_stock”: true}’ | boolean |
| <@ | Is contained by | ARRAY[‘a’,’b’] <@ tags | boolean |
| -> | Get JSON object field as jsonb | data -> ‘address’ | jsonb |
| ->> | Get JSON object field as text | data ->> ‘city’ | text |
| || | String / array concatenation | name || ‘ ‘ || surname | text / array |
| + – * / | Arithmetic | price * 1.18 | numeric |
| BETWEEN | Inclusive range | year BETWEEN 2000 AND 2010 | boolean |
| IN | Membership | status IN (‘shipped’,’delivered’) | boolean |
| IS NULL | Null check | phone IS NULL | boolean |
| AND / OR | Logical | price < 500 AND stock > 0 | boolean |
Your mini homework right now
Try these in your bookstore_demo (or college_db):
- Find books cheaper than βΉ300 using <
- Find customers whose email contains βgmailβ using ILIKE
- Use ->> if you added any JSONB column
- Use && if you add a tags array column
Next class?
Tell me:
- Want deep dive into JSONB operators (most powerful in 2026)?
- Full-text search operators & tsvector / tsquery?
- Array operators with real use-cases?
- Or custom operators / operator classes (advanced)?
Your guru is ready β what’s the next topic? π
