How to Practise SQL Without a Real Database

You can practise SQL without borrowing a real company’s database. A local SQL Server instance and a few carefully chosen rows are enough to test most query fundamentals.

Small wooden practice blocks in varied shapes beside an open blank notebook on an oak table.

Use an Engine Without Borrowing Production Data

You still need something that executes T-SQL, but you do not need confidential business data. A local development instance provides a useful place to learn. Keep the environment separate from systems that people depend on.

Official sample databases add realistic relationships when you want a larger exercise. AdventureWorks and WideWorldImporters are familiar options with documented schemas. Check the supported version and restore instructions before choosing a backup.

Begin smaller when the question is narrow. A complicated sample database can hide the behavior you are trying to understand. A dozen carefully selected values often teaches more than an unexplained million-row table.

Invent Rows That Answer One Question

Start with VALUES and a common table expression. Include a duplicate, a missing value, and a case that does not match. These examples are deliberately constructed, so you can reason about them before execution.

WITH Orders AS
(
    SELECT * FROM (VALUES
      (1, N'North', 10),
      (2, N'North', NULL),
      (3, N'South', 25),
      (4, N'South', 25)
    ) AS v(OrderId, Region, Amount)
)
SELECT Region, COUNT(*) AS order_count,
       COUNT(Amount) AS known_amount_count,
       SUM(Amount) AS amount_total
FROM Orders
GROUP BY Region;

Predict which rows contribute to each aggregate. Then change one input and explain the difference. The exercise is not complete until you can describe why the result changed.

Generate Scale Deliberately

When you need more rows, generate them with a known distribution. Do not assume evenly spaced values resemble real traffic. Repeated keys, skew, and recent-date concentration can change plans and estimates.

WITH Digits AS
(
    SELECT n FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) AS d(n)
), Numbers AS
(
    SELECT a.n + 10*b.n + 100*c.n AS n
    FROM Digits AS a CROSS JOIN Digits AS b CROSS JOIN Digits AS c
)
SELECT n AS RowId,
       CASE WHEN n < 800 THEN 1 ELSE 2 + n % 9 END AS CustomerId,
       DATEADD(day, n % 30, CONVERT(date, '20260101', 112)) AS OrderDate
FROM Numbers;

The distribution here is part of the example definition, not a measured claim about any existing table. Adjust it to answer a specific question. If testing indexes, put the generated rows into a lab table and record its definition.

Keep correctness tests separate from performance experiments. Small examples are excellent for semantics. Performance conclusions need representative scale, shape, configuration, and your own measurements.

Break a Rule on Purpose

A good lab includes controlled failures. Try a duplicate key, an invalid conversion, or a missing relationship in disposable objects. Learn to read the complete error rather than only its first line.

DECLARE @Keys table (Id int PRIMARY KEY);
INSERT @Keys VALUES (1);
BEGIN TRY
    INSERT @Keys VALUES (1);
END TRY
BEGIN CATCH
    SELECT ERROR_NUMBER() AS error_number,
           ERROR_MESSAGE() AS error_message;
END CATCH;

This example confines the duplicate-key experiment to a table variable. Other exercises may require a dedicated database and explicit cleanup. Know what the statement can change before pressing Execute.

Next, design the successful version and explain which rule it respects. Suppressing the error is not always the fix. Sometimes the correct application behavior is to reject the input clearly.

Turn Each Week Into a Small Experiment

Choose one topic for the week, such as joins, date boundaries, or transaction behavior. Spend the first session predicting results and the next testing edge cases. Finish by explaining the lesson without copying the original tutorial.

WITH Events AS
(
    SELECT EventTime FROM (VALUES
      (CONVERT(datetime2, '2026-01-31T23:59:59', 126)),
      (CONVERT(datetime2, '2026-02-01T00:00:00', 126))
    ) AS v(EventTime)
)
SELECT EventTime
FROM Events
WHERE EventTime >= CONVERT(date, '20260101', 112)
  AND EventTime < CONVERT(date, '20260201', 112);

For this exercise, ask why the upper boundary is exclusive. Then change the precision or reporting period without changing the intended meaning. A useful routine produces questions, not just completed videos.

Keep a Notebook of Explanations

Save the smallest runnable example, the engine version, and the result you actually observed. Separate predictions from measurements. Include the mistaken assumption that made the exercise worthwhile.

Revisit an older exercise after several weeks and solve it without the answer. If the code still needs a private explanation, improve the note. Practice becomes durable when another person could repeat it from what you saved.

SQL practice is not access to impressive data, it is a repeatable question and an honest test.

This post was rewritten from scratch in September 2026. The original, published on 2010-11-20, was a short announcement about something that no longer exists. The address is the same, the subject is now something worth keeping.

Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.

Best Practices, Database, SQL Scripts, SQL Server
Previous Post
Recording Table Row Counts Every Day
Next Post
SQL SERVER – Change Database Access to Single User Mode Using SSMS

Related Posts

5 Comments. Leave new

  • Hello Pinal.

    Got 1.

    Thanks for sharing.

    ~ IM.

    Reply
  • Feriecenter Vesterhavet
    November 21, 2010 6:42 am

    Thanks alot for the recommedation – I have just ordered the book.
    Thanks for sharing!

    Reply
  • Hi Pinal Sir,

    Thanks For sharing this book.
    Now,I wil read it and i wil share my experience.

    Thanks

    Reply
  • Thank you for the review, will check it out.

    Reply
  • Agreed! This book somehow seduces you into typing out the examples. There is just enough understanding to get you curious to try them, but not so much detail that you fall asleep before finishing a page. ( like the one from Itzak) no offense to him, but his book is far too deep for a beginner with TSQL.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.