Exploring an unfamiliar database

Lesson 8 of 10 · 18 min0/4 checked in practice
Objective

By the end of this lesson you can explore an unknown database with SQL alone: list its tables, count rows, preview rows with ORDER BY and LIMIT, and find which tables share a key column.

Why it matters: Real databases are big. Wadi Market has thousands of orders; a company warehouse can have billions of rows. Professionals never start with SELECT * on a huge table; they measure, preview and map first, and the questions get easier after that.

Dataset: Wadi Market online store. Examples run in the editor on the right.

Time to leave the corner shop. Wadi Market is a fictional online retailer in Riyadh that sells electronics, home goods, fashion and gourmet food through its website, app and a marketplace. Its database has eight tables and tens of thousands of rows: too big to read by eye, and realistic enough to have the quirks real data has.

When you meet a database like this, use a four-step routine:

  1. List the tables.
  2. Measure them: how many rows each has.
  3. Preview a handful of rows of each important table.
  4. Map the keys that connect them.
ExampleStep 1: list the tables
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public';

Eight tables: categories, customers, order_items, orders, payments, products, returns and shipments. The names already tell a story: customers place orders, orders contain items, items are products, and orders get paid, shipped and sometimes returned.

Step 2: measure

Before previewing a table, find out how big it is with count(*). Size changes how you work: you can read 18 rows, but not 15,000.

ExampleHow many orders?
SELECT count(*) AS order_count
FROM orders;

About six thousand orders (6,221 in this copy of the data). One row per order, so that's the number of orders Wadi Market has received from 2023 to the end of 2025.

Step 3: preview safely with ORDER BY and LIMIT

LIMIT n stops the result after n rows. On its own, though, it returns some n rows, whichever PostgreSQL meets first, because rows have no built-in order. Pair it with ORDER BY to make the preview predictable: ORDER BY column sorts ascending (smallest first), and ORDER BY column DESC sorts descending (largest or newest first).

SELECT column_one, column_two
FROM table_name
ORDER BY sort_column DESC
LIMIT 10;
Preview: sort, then keep the first 10 rows. ORDER BY comes after FROM; LIMIT comes last.
ExampleStep 3: the five newest orders
SELECT order_id, customer_id, ordered_at, channel, status
FROM orders
ORDER BY ordered_at DESC
LIMIT 5;

Five rows from the last day of 2025. ordered_at is a timestamp (a date plus a time), so DESC puts the most recent first. Recent orders are mostly still 'paid' or 'pending', because they haven't been shipped yet.

Previewing taught you things the schema couldn't: order ids start at 100001, channel holds values like web, app and marketplace, and coupon_code is often NULL. Those details save you from wrong assumptions later.

Step 4: map the connections

Tables connect through shared key columns, usually with the same name on both sides. To see which tables carry a given key, search information_schema.columns by column name.

ExampleStep 4: which tables mention customers?
SELECT table_name, column_name, data_type
FROM information_schema.columns
WHERE column_name = 'customer_id';

Two tables: customers, where customer_id is the primary key, and orders, where it is a foreign key. So to get from a payment to a customer you must go payment → order → customer; there is no shortcut.

Wadi Market's full map, which you'll use for the rest of the course, looks like this:

customers 1─* orders 1─* order_items *─1 products *─1 categories
orders 1─* payments
orders 1─* shipments
returns → order_items (order_id, product_id)

The dataset explorer and the schema panel show the same picture with descriptions of every column. Read them whenever a column name isn't self-explanatory: for example, the value of an order is not stored anywhere; it has to be calculated from its items.

Quick check
Quick check

You run SELECT * FROM order_items LIMIT 5; twice and get different rows. Why?

Now practise
4 exercises on real data, checked in your browser (practice).