DISTINCT, BETWEEN, IN & LIKE
BeginnerDISTINCT eliminates duplicate result rows; BETWEEN tests range membership; IN tests set membership; LIKE performs pattern matching with wildcard characters.
Overview
These four operators cover the most common filtering and deduplication patterns. DISTINCT operates on the entire selected row, not individual columns. BETWEEN is inclusive on both ends (BETWEEN 10 AND 20 includes both 10 and 20). IN is syntactic sugar for multiple OR equality checks and short-circuits as soon as a match is found. LIKE uses % (any sequence of characters) and _ (exactly one character); leading wildcards like LIKE '%text' cannot use a standard B-Tree index and always trigger a sequential scan. For case-insensitive pattern matching, PostgreSQL offers ILIKE and the pg_trgm extension for indexed full-text-like searches.
DISTINCT, BETWEEN, IN
DISTINCT removes duplicate rows from the result. It is applied after all projections, meaning two rows are duplicates only if ALL selected columns are equal. BETWEEN and IN simplify compound range/equality conditions.
-- DISTINCT: unique product categories ordered by a customer
SELECT DISTINCT product_category
FROM order_items oi
JOIN products p ON p.id = oi.product_id
WHERE oi.user_id = 42;
-- DISTINCT ON (PostgreSQL only): keep one row per distinct value in given columns
SELECT DISTINCT ON (user_id)
user_id, order_id, total_amount, created_at
FROM orders
ORDER BY user_id, created_at DESC; -- keeps latest order per user
-- BETWEEN (inclusive on both ends)
SELECT id, total_amount
FROM orders
WHERE total_amount BETWEEN 100.00 AND 500.00
AND created_at BETWEEN '2024-01-01' AND '2024-12-31';
-- IN: equivalent to multiple OR conditions (cleaner syntax)
SELECT id, email FROM users
WHERE status IN ('active', 'trial', 'grace_period');
-- NOT IN pitfall: if the list contains a NULL, entire result can be empty!
SELECT id FROM users
WHERE id NOT IN (1, 2, NULL); -- returns 0 rows! NULL poisons NOT IN
-- Fix: use NOT EXISTS or filter NULLs from the listLIKE and Pattern Matching
LIKE is case-sensitive in PostgreSQL. A leading wildcard (LIKE '%value') cannot use a standard B-Tree index. Use pg_trgm GIN indexes or full-text search for efficient substring matching.
-- LIKE: % = any chars, _ = exactly one char
SELECT id, email FROM users
WHERE email LIKE '%@gmail.com'; -- suffix match: full table scan!
SELECT id, sku FROM products
WHERE sku LIKE 'ELEC-%'; -- prefix match: CAN use a B-Tree index
-- ILIKE: case-insensitive LIKE (PostgreSQL only)
SELECT id, full_name FROM employees
WHERE full_name ILIKE 'john%'; -- matches John, JOHN, john
-- MySQL: LIKE is case-insensitive for case-insensitive collations (utf8mb4_general_ci)
-- Enabling fast substring search with pg_trgm (PostgreSQL)
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE INDEX idx_products_name_trgm ON products USING GIN (name gin_trgm_ops);
-- Now LIKE '%laptop%' or ILIKE '%laptop%' can use the GIN index
SELECT id, name FROM products WHERE name ILIKE '%laptop%';
-- REGEXP / SIMILAR TO for complex patterns (no index support)
SELECT id, phone FROM users WHERE phone ~ '^+91[0-9]{10}$';Key Points to Remember
- 1DISTINCT deduplicates on the full projected row — not on a single column.
- 2BETWEEN is inclusive: BETWEEN 10 AND 20 includes both 10 and 20.
- 3NOT IN with a NULL in the list returns zero rows due to three-valued logic.
- 4LIKE with a leading wildcard ('%text') cannot use a B-Tree index.
- 5LIKE 'prefix%' (no leading wildcard) CAN use a B-Tree index.
- 6Use pg_trgm GIN index for efficient LIKE '%substring%' queries in PostgreSQL.
Interview Questions
Sign in to ask AriaWhy does NOT IN return no rows when the subquery contains a NULL?
What is the difference between LIKE '%text' and LIKE 'text%' in terms of index usage?
How does DISTINCT ON differ from DISTINCT in PostgreSQL?
How would you implement efficient case-insensitive search in PostgreSQL?
Ask Aria about DISTINCT, BETWEEN, IN & LIKE
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.