Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

SQL (Structured Query Language) is the language used to read, create, change and delete data in relational databases. Its basic rules are few: data sits in tables made of rows and columns, a SELECT statement names the data you want, clauses such as WHERE and ORDER BY filter and sort the result, and a join combines related rows from two tables. The examples below are labelled PostgreSQL where the syntax is product-specific, because SQL implementations do not behave identically in every detail.

How relational data is organized

A relational database stores information in tables. Each table has columns, which define the kinds of information kept (a name, a city, an amount), and rows, which hold one record each. Tables are linked by shared values: an order row can carry the ID of the customer who placed it, so you can find which customer an order belongs to without copying the customer’s details into every order.

The examples in this guide use two small tables.

customers id name city
1 Amara Okafor Lagos
2 Ben Clarke Leeds
3 Chen Wei Shanghai
orders id customer_id total
101 1 250
102 1 80
103 2 410

Chen Wei has no orders, which becomes important when we reach joins.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keywords, identifiers and literals

Every SQL statement is built from a few kinds of tokens. Learning to tell them apart makes error messages much easier to read.

  • Keywords have a fixed meaning to the language, such as SELECT, FROM, WHERE, ORDER BY, JOIN and ON. You cannot use them as table or column names without quoting them.
  • Identifiers are the names you or the database owner choose for objects: customers, name, customer_id.
  • Literals are fixed values written into a statement. Text goes in single quotes ('Leeds'); numbers do not (100).
  • Operators compare or combine values: = (equal), > (greater than), < (less than), AND, OR.
  • Comments begin with -- and run to the end of the line. Use them to annotate examples you save.

Retrieving data with SELECT

A query is a question about stored data. In its simplest form, SELECT lists the columns you want and FROM names the table they come from.

Selecting named columns

SELECT name, city
FROM customers;

This returns three rows: Amara Okafor (Lagos), Ben Clarke (Leeds) and Chen Wei (Shanghai). Writing SELECT * returns every column and is convenient when you are exploring an unfamiliar table. For queries you keep or share, name the columns: the reader can see at a glance what the output contains, and the query keeps working if someone later adds a column.

Filtering rows with WHERE

A WHERE clause keeps only the rows for which its condition is true. It is the place where a question such as “which customers live in Leeds?” becomes code.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
SELECT name, city
FROM customers
WHERE city = 'Leeds';

The result is one row: Ben Clarke, Leeds. Conditions can be combined with AND and OR, and comparisons work on numbers as well as text. For example, WHERE total > 100 keeps only orders above 100.

Sorting results with ORDER BY

ORDER BY states the sort you want. Without it, a database makes no promise about the order in which rows come back, so never rely on the apparent order of a result you did not sort.

SELECT id, total
FROM orders
WHERE total > 100
ORDER BY total DESC;

This returns order 103 (410) followed by order 101 (250). DESC sorts from highest to lowest; ASC, the default, sorts from lowest to highest.

Combining related tables with joins

A join matches rows from two tables using a condition, usually an equality between a key in one table and the matching key in the other. Write the condition in an explicit ON clause, and qualify column names with a table alias (here c and o) so the database and the reader can tell which table each column belongs to. The following examples use PostgreSQL syntax.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Inner join: rows that match on both sides

SELECT c.name, o.id AS order_id, o.total
FROM customers AS c
JOIN orders AS o ON o.customer_id = c.id
ORDER BY c.id, o.id;

An inner join returns only pairs that match. The result contains Amara Okafor with orders 101 and 102, and Ben Clarke with order 103. Chen Wei does not appear, because there is no order row that matches her.

Left join: keep every row from the left table

SELECT c.name, o.id AS order_id, o.total
FROM customers AS c
LEFT JOIN orders AS o ON o.customer_id = c.id
ORDER BY c.id, o.id;

A left join keeps every row from the left-hand table, here customers. Chen Wei now appears, and because there is no matching order, the right-hand columns order_id and total are NULL for her row. That is the most common reason to choose a left join: finding the left-side rows that have no partner, such as customers who have never ordered.

SELECT c.name
FROM customers AS c
LEFT JOIN orders AS o ON o.customer_id = c.id
WHERE o.id IS NULL;

This returns Chen Wei alone.

NULL: a missing value, not a zero or an empty string

NULL marks a value that is unknown or absent. It is not the number 0 and not an empty text string, and it does not equal anything, including another NULL. For that reason, a comparison such as total = NULL does not find NULL values in PostgreSQL; use IS NULL or IS NOT NULL instead, as in the left-join example above. Check how your database handles NULL in aggregates and sorting before you depend on those results, because the behaviour is documented per system.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Changing data: INSERT, UPDATE, DELETE and CREATE TABLE

SQL is not only for reading data. The same language creates tables and changes their contents. The PostgreSQL tutorial covers table creation, inserting rows, updates and deletions alongside queries. Here is a quick preview, again in PostgreSQL syntax:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
CREATE TABLE notes (
    id integer PRIMARY KEY,
    body text
);

INSERT INTO customers (id, name, city)
VALUES (4, 'Dana Ruiz', 'Madrid');

UPDATE orders
SET total = 90
WHERE id = 102;

DELETE FROM orders
WHERE id = 102;

Updates and deletes are where beginners cause the most damage. The WHERE clause decides which rows change, and an UPDATE or DELETE without one applies to every row in the table. Practise on a scratch database, and follow these steps for any change you have not run before:

  1. Write the matching SELECT first, using the same WHERE condition, and confirm it returns exactly the rows you expect.
  2. Run the change inside a transaction in PostgreSQL (BEGIN; then the statement), and check the reported row count.
  3. Run COMMIT; only when the count matches; run ROLLBACK; if it does not.

Where SQL implementations differ

SQL is a standard family of languages, but each database system implements its own dialect. PostgreSQL’s syntax documentation notes that some rules are inconsistent across database systems and some are specific to PostgreSQL. Differences that commonly matter for beginners include:

  • Syntax extensions and keywords that exist in one system only.
  • Data type names and how values of each type behave in expressions.
  • Details of join, NULL and sorting behaviour in edge cases.
  • The tools used to run statements and how they display results.

When you move a query to another system, treat its vendor documentation as the authority. The basic rules in this guide (tables, SELECT, WHERE, ORDER BY, joins, and NULL as a missing value) apply broadly, but the exact syntax may not transfer unchanged.

Where to continue

The PostgreSQL 17 Tutorial is a free, hands-on introduction to PostgreSQL, relational database concepts and the SQL language. It describes itself as introductory rather than comprehensive, so treat it as a starting point and use the reference documentation for complete syntax and behaviour. Work through it with a practice database, and recreate the two sample tables above to test each query before moving on.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Source: PostgreSQL 17 Tutorial, PostgreSQL Global Development Group.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.