All 40 lessons

Lesson 6 of 40 · SQL Basics

SQL IN, BETWEEN and LIKE

By Skillancy Editorial Team

Every example runs on the ShopKart dataset, already loaded in the free SQL Compiler. Click Try it in the SQL Compiler under a query to open it there, then press Run.

IN matches any value in a list, BETWEEN matches a range, and LIKE matches a text pattern. They are shortcuts that make WHERE clauses shorter and easier to read.

Syntax

WHERE column IN (value1, value2, ...)
WHERE column BETWEEN low AND high
WHERE column LIKE 'pattern'

IN

1. Match a list of values

Customers from the four southern metros:

SELECT customer_name, city
FROM customers
WHERE city IN ('Bengaluru', 'Chennai', 'Hyderabad', 'Kochi');
Try it in the SQL Compiler

Result:

customer_namecity
Aarav SharmaBengaluru
Priya NairKochi
Sneha ReddyHyderabad
Ananya IyerChennai
Divya MenonBengaluru

(5 rows)

This is the same as writing city = 'Bengaluru' OR city = 'Chennai' OR ..., just shorter.

2. NOT IN

Orders that are still open (not delivered, cancelled or returned):

SELECT order_id, status
FROM orders
WHERE status NOT IN ('Delivered', 'Cancelled', 'Returned');
Try it in the SQL Compiler

Result:

order_idstatus
1020Shipped
1022Shipped
1023Pending
1024Pending

(4 rows)

BETWEEN

3. A numeric range

Products priced from ₹500 to ₹2,500, inclusive:

SELECT product_name, price
FROM products
WHERE price BETWEEN 500 AND 2500
ORDER BY price;
Try it in the SQL Compiler

Result:

product_nameprice
Steel Water Bottle 1L549.00
Yoga Mat 6mm799.00
Non-stick Tawa899.00
boAt Airdopes 1411299.00
Men's Cotton Kurta1899.00
Prestige Pressure Cooker 5L2199.00
Running Shoes2499.00

(7 rows)

Both ends are included: a product at exactly ₹2,500 would appear.

4. A date range

Orders from the April–June 2025 quarter:

SELECT order_id, order_date
FROM orders
WHERE order_date BETWEEN '2025-04-01' AND '2025-06-30';
Try it in the SQL Compiler

Result:

order_idorder_date
10072025-04-15
10082025-05-03
10092025-05-21
10102025-06-09
10112025-06-30

(5 rows)

This is safe because order_date is a DATE. For TIMESTAMP columns, use order_ts >= '2025-04-01' AND order_ts < '2025-07-01' so you don't lose orders placed after midnight on the last day.

LIKE and wildcards

WildcardMatchesExampleMatches…
%any number of characters (including none)'S%'Samsung, Saree
_exactly one character'_aree'Saree

5. Starts with

Customers whose name starts with "A":

SELECT customer_name
FROM customers
WHERE customer_name LIKE 'A%';
Try it in the SQL Compiler

Result:

customer_name
Aarav Sharma
Ananya Iyer
Arjun Patel

(3 rows)

6. Contains

Customers with a Gmail address:

SELECT customer_name, email
FROM customers
WHERE email LIKE '%@gmail.com';
Try it in the SQL Compiler

Result:

customer_nameemail
Aarav Sharmaaarav.sharma@gmail.com
Sneha Reddysneha.reddy@gmail.com
Vikram Singhvikram.singh@gmail.com
Ananya Iyerananya.iyer@gmail.com
Ishita Dasishita.das@gmail.com
Arjun Patelarjun.patel@gmail.com
Meera Kulkarnimeera.k@gmail.com
Farhan Khanfarhan.khan@gmail.com

(8 rows)

7. Case-insensitive search with ILIKE

LIKE is case-sensitive in PostgreSQL. A search box needs to match "face", "Face" and "FACE":

SELECT product_name
FROM products
WHERE product_name ILIKE '%face%';
Try it in the SQL Compiler

Result:

product_name
Herbal Face Wash
Kumkumadi Face Oil

(2 rows)

In MySQL or SQL Server, use LOWER(product_name) LIKE '%face%'.

Common mistakes

NOT IN with a NULL in the list. This returns nothing, because x <> NULL is never true:

SELECT customer_name
FROM customers
WHERE phone NOT IN ('9876543210', NULL);
Try it in the SQL Compiler

Result:

(0 rows)

Keep NULLs out of NOT IN lists, or use NOT EXISTS (covered in the EXISTS lesson).

  • BETWEEN with the high value first. BETWEEN 2500 AND 500 returns nothing.
  • A leading % on huge tables. LIKE '%term' can't use a normal index, so it scans every row. Fine for learning, slow on millions of rows.

Practice question

Find products from the brands Prestige, Milton or Hawkins that cost between ₹500 and ₹1,000.

Show solution
SELECT product_name, brand, price
FROM products
WHERE brand IN ('Prestige', 'Milton', 'Hawkins')
  AND price BETWEEN 500 AND 1000;
Try it in the SQL Compiler

Result:

product_namebrandprice
Steel Water Bottle 1LMilton549.00
Non-stick TawaHawkins899.00

(2 rows)

Key takeaways

  • IN replaces a chain of OR conditions on one column.
  • BETWEEN is inclusive at both ends; be careful with timestamps.
  • % matches any run of characters, _ matches exactly one.
  • Use ILIKE (PostgreSQL) or LOWER() for case-insensitive search.

Frequently asked questions

Is BETWEEN inclusive in SQL?

Yes. BETWEEN 100 AND 500 includes both 100 and 500. With timestamps be careful: BETWEEN '2025-01-01' AND '2025-01-31' misses times later on 31 January. Use >= start AND < next_day instead.

What is the difference between LIKE and ILIKE?

LIKE is case-sensitive in PostgreSQL, ILIKE is case-insensitive. ILIKE is PostgreSQL-only; in other databases use LOWER(column) LIKE 'pattern'.

Why does NOT IN return no rows?

If the list or subquery inside NOT IN contains a NULL, the condition can never be true, so no rows come back. Use NOT EXISTS or filter out NULLs.

Newsletter

Keep learning SQL

One email a week with SQL and analytics guides, new practice questions and cohort dates. No spam, unsubscribe anytime.

Prefer a one-page summary? Download the free SQL cheat sheet (PDF)