SQL Boy
TutorialsPlayground

Format & Validate

SQL FormatterSQL MinifierSyntax Validator

Convert

JSON to SQLCSV to SQLSQL to JSONRegex to SQLExcel to SQLSQL Dialect Convertersoon

Visualize

ER Diagram GeneratorSQL Schema Diff

Generate

SQL Mock Data Generator

Analyze

SQL Query ExplainerSQL Query Analyzer

Workflow hubs

FormattingConversionSchemaAnalysis
View all tools
Daily ChallengeInterviewsCheat SheetBlog

© 2026 SQL Boy. Built for developers.

ContactPrivacyTermsAI Usage PolicyEditorial StandardsAboutRSS Feed

New conversation

What can I help with?

Ask about this page, get a hint on a challenge, or explore SQL concepts.

I know what's on this page and can give answers grounded in SQL Boy content.

Current page

Building Simple Search Engine Sql

/blog/building-simple-search-engine-sql

Usage status will load after login
SQL Boy
TutorialsPlayground

Format & Validate

SQL FormatterSQL MinifierSyntax Validator

Convert

JSON to SQLCSV to SQLSQL to JSONRegex to SQLExcel to SQLSQL Dialect Convertersoon

Visualize

ER Diagram GeneratorSQL Schema Diff

Generate

SQL Mock Data Generator

Analyze

SQL Query ExplainerSQL Query Analyzer

Workflow hubs

FormattingConversionSchemaAnalysis
View all tools
Daily ChallengeInterviewsCheat SheetBlog
Back to Blog
Published 2026-01-15
Updated 2026-04-20
6 min read

Building a Weighted Search Engine with Pure SQL

sqlitesearchrankingcase-statementsbeginners

Author

SQL Boy Team

Editorial Team at SQL Boy

This article is maintained as part of SQL Boy's hands-on SQL library.

We aim to keep examples runnable, call out dialect differences, and revise unclear sections over time.

Read editorial standardsAbout SQL BoyRequest a correction

If a result or dialect note looks wrong, email [email protected] with the article URL and the section you want reviewed.

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

A Real Business Scenario: Search That Feels Better Without a New Service

Many internal tools, catalogs, and admin dashboards do not need a dedicated search stack on day one. They need a search result order that feels reasonable to humans.

Typical examples:

  • a product picker where exact names should beat partial matches
  • a help-center lookup where title matches should outrank description matches
  • an internal admin tool where "Pro Max" should beat "Programming Book" for the query pro

That is where weighted SQL search works well. It gives you control over ranking without introducing a separate indexing system too early.

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

A Common Mistake: Leading Wildcards Everywhere

The easiest search pattern to write is also often the hardest to scale:

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

The leading % means "match anywhere", which is flexible but often prevents ordinary prefix indexing from helping. That can be fine for small datasets. It becomes a problem when the table grows and every request scans a large portion of the column.

If your product can tolerate prefix matching for the first pass, query% is often much cheaper than %query%.

Boundary and Performance Notes

Weighted LIKE search is a good middle ground, but it has limits.

  • It works best on small to medium tables or on filtered subsets where full scans are still acceptable.
  • Ranking logic becomes harder to maintain as soon as you add many fields, language rules, typo tolerance, or stemming.
  • Case normalization with LOWER() can reduce index friendliness unless you use database features such as functional indexes or normalized search columns.
  • Search quality and search speed are separate problems. A query can rank results reasonably but still be too expensive on a hot path.

The right question is not just "Can SQL do search?" but "At what scale and quality level does this still remain the simplest good solution?"

When NOT to Use This Pattern

Move beyond weighted LIKE when:

  • you need typo tolerance, stemming, or language-aware ranking
  • relevance depends on many text fields with competing weights
  • result latency must stay low on large datasets under real user traffic

At that point, full-text search, trigram search, or a dedicated search service may be a better fit than continuing to pile more CASE branches onto one query.

Official References

  • SQLite query planner overview for how pattern matching and indexing interact in SQLite.
  • PostgreSQL pattern matching documentation for LIKE, ILIKE, and regex alternatives in a major SQL engine.
  • SQLite FTS5 documentation for the next step once weighted LIKE search stops being sufficient.

Tool Workflow

Use tools when lightweight SQL search starts turning into a real query-design problem

Weighted LIKE search works well for small and medium datasets, but once matching logic, ranking, and safety concerns pile up it helps to inspect the final query and compare it against stronger search patterns.

Regex to LIKE Converter

Convert broader search ideas into SQL-friendly pattern matching before you wire them into ranking logic.

SQL Query Analyzer

Review search-query shape and performance risk before a LIKE-based search becomes a production bottleneck.

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.

Related Articles

  • Using Regular Expressions in SQL: Pattern Matching Deep Dive for more expressive text-matching patterns before or alongside LIKE-based ranking.
  • SQLite Full-Text Search FTS5 Explained for the next step when basic contains matching starts to hit scalability limits.
  • SQL CASE Statements Explained for the branching logic that powers weighted search scoring.
Share this article:

Related Articles

beginners

SQL Table Relationships: One-to-Many and Many-to-Many

Learn the two most important database relationships. Design one-to-many and many-to-many tables with real SQL examples, diagrams, and interactive queries.

Read more
sqlite

Full-Text Search in SQLite with FTS5

Go beyond LIKE queries. Learn how to build lightning-fast full-text search using SQLite FTS5 virtual tables with BM25 relevance ranking.

Read more
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
Previous

Generating Massive Test Data with SQL (No Scripts Required)

Next

Calculating Running Totals & Moving Averages in SQL

Comments

© 2026 SQL Boy. Built for developers.

ContactPrivacyTermsAI Usage PolicyEditorial StandardsAboutRSS Feed