Tables, rows and columns

Lesson 2 of 10 · 14 min0/4 checked in practice
Objective

By the end of this lesson you can describe any table by its grain (what one row is), its columns and their types, and count its rows with a query.

Why it matters: Knowing what one row of a table represents is the first thing every analyst checks. Most wrong numbers in reports come from misunderstanding a table's grain, not from bad SQL.

Dataset: Starter shop. Examples run in the editor on the right.

A relational database stores data in tables (the formal word is relations, which is where the name comes from). Every table follows the same rules:

  • A table has a name that describes what it holds, usually a plural noun: customers, products, orders.
  • A column is one kind of fact, with a name and a data type. Every value in the price column is a number; every value in joined_on is a date.
  • A row (or record) is one thing: one customer, one product, one order. It has exactly one value (or NULL) in every column.
  • The value where a row meets a column is a cell, or simply a value.

Explore the parts below. Click each highlight and read what it means.

customers
idnamecity
1NouraRiyadh
2FaisalJeddah
3SaraNULL
4OmarRiyadh

A row (record) is one customer: every column's value for that one thing.

A row is one customer, a column is one kind of fact, the primary key identifies each row, and NULL marks a missing value.

Grain: what is one row?

The single most useful question about a table is: what does one row represent? That is its grain. In Corner Market:

  • customers: one row per registered customer.
  • products: one row per item for sale.
  • orders: one row per order, and each order is for exactly one product.

If you know the grain, you know what counting rows means. Counting the rows of orders gives the number of orders, not the number of customers who ordered (one customer can have many orders) and not the number of units sold (an order can have a quantity of 3).

To count rows, use count(*). It's your first function: a built-in tool that takes rows in and gives a value back. You'll study counting properly in the aggregation track; for now it's a handy way to measure a table.

ExampleHow many customers does the shop have?
SELECT count(*) AS customer_count
FROM customers;

count(*) counts the rows that FROM produced: 12, one per customer. AS customer_count gives the result column a readable name. The answer is a table with one row and one column.

Data types keep columns honest

Each column is declared with a type, and the database refuses values that don't fit. The starter tables use four common types:

typeholdsexample
integerwhole numbersstock = 17
numeric(12,2)exact decimals, here with 2 decimal placesprice = 75.50
textwords and characters of any lengthcity = 'Jeddah'
datea calendar dateorder_date = 2025-03-08

Types matter because they decide what you can do with a value: you can add prices, but not cities, and you can ask which date is earlier.

NULL: no value recorded

Sometimes a value is simply not known: a customer never told the shop their city. The database stores NULL in that cell. NULL is not zero, not an empty piece of text and not the word 'NULL'; it means missing. One Corner Market customer has a NULL city and two have a NULL email. Look for them in the next example.

ExampleEvery customer, every column
SELECT *
FROM customers;

12 rows, one per customer. Scan the city and email columns: one city and two emails show NULL. Those customers still exist; only those particular facts are missing.

Why split data into several tables?

Why not one giant sheet with the customer's name, city and email repeated on every order? Because repeated facts drift apart. If Noura moves to Jeddah, a single-sheet design must update every one of her orders, and missing one leaves the data contradicting itself.

A relational design stores each fact once, in the table it belongs to. The orders table doesn't repeat Noura's name or city; it stores her customer number, customer_id, which points to her one row in customers. That pointer is a relationship, and the next lesson is all about it.

Quick check
Quick check

The orders table has one row per order. A customer who placed three orders appears how many times in it?

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