SQL Playground
TutorialsPlayground
SQL FormatterSQL MinifierSyntax ValidatorJSON to SQLCSV to SQLSQL to JSONER Diagram Generator
Daily ChallengeInterviewsCheat SheetBlog

© 2026 SQL Playground. Built for developers.

PrivacyTermsAboutRSS Feed
SQL Playground
TutorialsPlayground
SQL FormatterSQL MinifierSyntax ValidatorJSON to SQLCSV to SQLSQL to JSONER Diagram Generator
Daily ChallengeInterviewsCheat SheetBlog
Back to Blog
2026-01-15
3 min read

Building a Weighted Search Engine with Pure SQL

sqlitesearchrankingcase-statementsbeginners

When adding search to an app, the temptation is to jump straight to heavy tools like Elasticsearch or Algolia. But for many projects, your database is already a powerful search engine.

The problem with a simple WHERE name LIKE '%query%' is that it's "dumb". It returns everything that matches, in no particular order. A user searching for "Apple" wants "Apple Store" to appear before "Pineapple".

In this guide, we'll build a "Smart" search engine that ranks results by relevance:

  1. Exact Match: The best.
  2. Starts With: Very good.
  3. Contains: Okay.

Search ranking with three tiers: exact match, starts with, and contains
Search ranking with three tiers: exact match, starts with, and contains

The Secret Sauce: CASE Statements

CASE statement logic flowchart showing how search queries are scored by relevance
CASE statement logic flowchart showing how search queries are scored by relevance

We can use a CASE statement in our ORDER BY clause to assign a "score" to each match type.

SELECT name,
  CASE 
    WHEN name LIKE 'query' THEN 1      -- Exact match
    WHEN name LIKE 'query%' THEN 2     -- Starts with
    WHEN name LIKE '%query%' THEN 3    -- Contains
    ELSE 4                             -- No match
  END as relevance
FROM products
WHERE name LIKE '%query%'
ORDER BY relevance ASC;

Interactive Example: Searching for "Pro"

Let's search a product catalog for the term "Pro". We expect "Pro Max" (Starts with) to appear before "GoPro" (Contains).

Interactive SQL
Loading...

Improving the Search: Case Insensitivity

By default, LIKE is case-insensitive in SQLite for ASCII characters, but it's good practice to be explicit, especially if moving to PostgreSQL later (where ILIKE is needed).

In SQLite, you can use the LOWER() function to normalize both sides:

WHERE LOWER(name) LIKE LOWER('%query%')

Multiple Keywords

If you need to search multiple columns (e.g., Title OR Description), simply add them to your CASE logic with different weights.

ORDER BY 
  CASE WHEN title LIKE '%query%' THEN 1 ELSE 10 END +
  CASE WHEN description LIKE '%query%' THEN 2 ELSE 10 END
  ASC

Conclusion

You don't need complex infrastructure to build a good search experience. By using CASE statements to weight your results, you can give users highly relevant results using nothing but standard SQL.

This approach scales well for datasets up to roughly 50,000 - 100,000 rows, which covers 95% of small to medium applications.

Share this article:

Related Articles

ranking

Ranking Data with SQL: RANK, DENSE_RANK, and ROW_NUMBER Explained

Building leaderboards, finding top performers, or paginating results? Master the three SQL ranking functions and understand exactly when to use each one.

Read more
sqlite

Calculating Running Totals & Moving Averages in SQL

How do you calculate "Year to Date" revenue or a "7-Day Moving Average" in SQL? The answer is Window Functions. Learn how to look back across rows without using self-joins.

Read more
sqlite

Generating Massive Test Data with SQL (No Scripts Required)

Need 1,000 rows to test your query performance? Don't write a Python script. Learn how to use Recursive CTEs to generate massive datasets directly in SQLite.

Read more
Previous

Generating Massive Test Data with SQL (No Scripts Required)

Next

Calculating Running Totals & Moving Averages in SQL

Comments

© 2026 SQL Playground. Built for developers.

PrivacyTermsAboutRSS Feed