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-14
3 min read

Generating Massive Test Data with SQL (No Scripts Required)

sqlitetestingctesperformancedata-generation

You've designed a great schema and wrote a clever query. But testing it on 5 rows isn't enough. You need to know how it performs with 10,000 or 100,000 rows.

Does this mean you need to write a Python script to generate CSVs and import them?

No! You can generate massive, realistic datasets purely with SQL using Recursive CTEs.

Recursive number series expanding into a large dataset
Recursive number series expanding into a large dataset

The Magic of WITH RECURSIVE

A Recursive CTE (Common Table Expression) allows a query to refer to itself. This is perfect for generating series (1, 2, 3...) which can then be transformed into data.

Generating a Number Series

Here is the "Hello World" of test data:

WITH RECURSIVE generate_series(value) AS (
  SELECT 1  -- Initial value
  UNION ALL
  SELECT value + 1 FROM generate_series
  WHERE value + 1 <= 10 -- Stop condition
)
SELECT value FROM generate_series;

Generating Random Data

Once you have a sequence of numbers, you can use SQLite's math functions to generate random attributes.

  • Random Integer (1-100): ABS(RANDOM()) % 100 + 1
  • Random Date: DATE('now', '-' || (ABS(RANDOM()) % 365) || ' days')
  • Random String: Use CASE or substring logic (though SQL is a bit limited here, we can fake it).

Interactive Example: Creating 1,000 Users

Let's generate a users table with 1,000 rows. We'll give them:

  • An ID
  • A random "Group" (A, B, C, D, E)
  • A random Signup Date within the last year
  • A random Activity Score (0-5000)
Interactive SQL
Loading...

Why random data matters

Generating random data is crucial for:

  1. Index Testing: An index behaves differently with 10 rows vs 100,000 rows.
  2. Query Optimization: You can't see "Slow Query" warnings if your query runs in 0.001ms on an empty table.
  3. UI Stress Testing: See how your frontend handles pagination, sorting, and large numbers.

Generating Dates

A common requirement is generating a continuous range of dates (e.g., "every day in 2024").

WITH RECURSIVE dates(date) AS (
  SELECT '2024-01-01'
  UNION ALL
  SELECT DATE(date, '+1 day')
  FROM dates
  WHERE date < '2024-12-31'
)
SELECT * FROM dates;

This is invaluable for "Filling the gaps" in charts where you have no sales for a specific day but still want the day to appear on the X-axis.

Conclusion

You don't need external tools to populate your database. With SQLite's WITH RECURSIVE, you have a powerful factory for synthetic data right at your fingertips.

Next time you need to test performance, don't guess—generate!

Share this article:

Related Articles

sqliteperformance

Simulating Materialized Views in SQLite with Triggers

SQLite doesn't support materialized views, but you can build them yourself! Learn how to use triggers to create high-performance cached summary tables.

Read more
performance

Mastering Temporary Tables in SQL

Need to store intermediate results without cluttering your database? Learn when and how to use Temporary Tables for complex analysis.

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
Previous

Mastering UPSERT in SQLite: The ON CONFLICT Clause

Next

Building a Weighted Search Engine with Pure SQL

Comments

© 2026 SQL Playground. Built for developers.

PrivacyTermsAboutRSS Feed