VMware ESXi and vSphere Cluster Management
Free Online SQL Course: Learn Database Basics
Learn SQL fundamentals from scratch: relational databases, SELECT, filtering, functions, grouping, INSERT, UPDATE, DELETE, table design, joins, and safe data changes.
SQL, pronounced either “S-Q-L” or “sequel,” is Structured Query Language. It is used to define, query, and manipulate data in relational database management systems. This beginner-friendly course introduces the core SQL skills needed to read and change structured data.
You do not need previous SQL or programming experience. You should be comfortable using a Windows computer, installing software, downloading applications, and understanding basic networking concepts such as IP addresses and Internet connectivity. Basic system administration knowledge is useful when starting and connecting a database server.
What SQL and Relational Databases Are
A database is an organized collection of data managed by software. A relational database management system, or RDBMS, stores data in related tables and provides tools for querying, protecting, and changing it. SQL is the language used to communicate with many RDBMS products.
| Term | Definition | Example |
|---|---|---|
| SQL | Structured Query Language for defining, querying, and manipulating relational data. | SELECT name FROM customers; |
| Database | An organized collection of data managed by a database system. | An online shop's sales database. |
| Database server | The software service that accepts connections and processes database requests. | A local database service on a Windows computer. |
| Table | A structured collection of related records arranged in rows and columns. | customers |
| Row | One record in a table. | One customer's complete record. |
| Column | One named data field in a table. | email or created_at |
| Query | An SQL statement sent to a database. | A request for orders placed this month. |
For example, a customers table might have columns named customer_id, name, and email. Each row describes one customer. An orders table can contain order_id, customer_id, order_date, and total_amount. The shared customer_id value lets the database relate orders to customers.
Setting Up and Connecting to a Database
SQL statements need a database program or server to run. You normally use two pieces of software:
- Database server: stores data, executes SQL, and manages users and permissions.
- Database client: a command-line tool or graphical application in which you enter SQL and view results.
Beginner setup on Windows
- Choose an RDBMS supported by your course or project.
- Download its official Windows installer from the product's trusted distribution source.
- Run the installer and note the server service, administrator account, port, and data directory choices.
- Set a strong password for the administrative account. Do not use production credentials for practice.
- Install a compatible database client if the server installer does not include one.
- Start the database service and create a separate practice database and user when appropriate.
- Connect with the client and run a simple test query such as
SELECT 1;.
Product names and default ports differ. Some systems use a local service, while others run in a container or on another computer. Follow the selected product's installation instructions rather than assuming that commands or settings are interchangeable.
Connection details
A client commonly asks for these values:
- Host or server address: the computer name, IP address, or local address.
- Port: the network endpoint on which the database service listens.
- Database name: the database to use after authentication.
- Username and password: the account credentials.
- Connection or authentication method: for example, password-based or integrated authentication.
For a local server, the host may refer to the same computer. For a network server, the host must be reachable and the firewall must permit the database port. Access also depends on database permissions. Avoid placing passwords in shared scripts or public source code.
SQL Syntax Fundamentals
An SQL statement is a complete instruction. Keywords such as SELECT, FROM, and WHERE have special meanings. Identifiers name objects such as tables and columns. Literals are values written directly in a statement, such as 42 or 'North'. A delimiter marks the end of a statement; the semicolon is the common delimiter, although client tools and database products can vary.
SELECT name, email -- columns and identifiers
FROM customers -- table identifier
WHERE status = 'active'; -- text literal and statement delimiter
SQL keywords are commonly written in uppercase and identifiers in lowercase or a consistent naming style. Most database systems treat keywords without regard to case, but identifier rules can differ. Use indentation, one clause per line, meaningful aliases, and comments beginning with --. Some systems also support block comments such as /* explanation */.
Common data types
- Text: character data such as names and email addresses, often represented by types such as
VARCHAR. - Integer: whole numbers such as quantities or identifiers.
- Decimal: exact numeric values such as prices; use an appropriate precision and scale.
- Date and time: dates, timestamps, or times.
- Boolean: true/false values where supported.
Exact type names, automatic conversions, date formats, identifier quoting, and semicolon behavior vary between RDBMS products. Learn the conventions of the system you are using.
SQL Statement Reference
| Statement | Purpose | Typical clauses | Example use case |
|---|---|---|---|
SELECT | Retrieve rows and expressions. | FROM, WHERE, GROUP BY, ORDER BY | Find customer email addresses. |
INSERT | Add rows. | INTO, column list, VALUES | Add a new customer. |
UPDATE | Modify existing rows. | SET, WHERE | Change one product price. |
DELETE | Remove rows. | FROM, WHERE | Remove identified test records. |
CREATE TABLE | Define a table and its columns. | Column types and constraints | Create a products table. |
Retrieving Data with SELECT
SELECT returns data. Use an asterisk to request every column, or name only the columns needed.
SELECT * FROM customers;
SELECT name, email
FROM customers;
Aliases give columns or tables clearer names in results. The AS keyword is commonly used, although some systems allow it to be omitted.
SELECT name AS customer_name,
email AS contact_email
FROM customers AS c;
Filtering rows with WHERE
WHERE keeps only rows that satisfy a condition.
| Operator | Meaning | Example condition |
|---|---|---|
= | Equal to | status = 'paid' |
<> or != | Not equal to; support varies | status <> 'cancelled' |
>, >= | Greater than or at least | total_amount >= 100 |
<, <= | Less than or at most | quantity < 10 |
AND | Both conditions must be true | status = 'paid' AND total_amount > 100 |
OR | At least one condition is true | status = 'paid' OR status = 'shipped' |
NOT | Negates a condition | NOT status = 'cancelled' |
Use parentheses when combining AND and OR so the intended logic is unmistakable.
SELECT order_id, order_date, total_amount
FROM orders
WHERE order_date BETWEEN '2026-01-01' AND '2026-01-31'
AND status IN ('paid', 'shipped')
ORDER BY order_date DESC;
IN compares a value with a list. BETWEEN expresses an inclusive range in many systems. For text patterns, LIKE uses % for any sequence of characters and _ for one character.
SELECT product_id, name
FROM products
WHERE name LIKE '%keyboard%';
NULL means an unknown, missing, or inapplicable value. It is not zero and is not an empty string. Do not use = NULL; use IS NULL or IS NOT NULL.
SELECT * FROM customers WHERE phone IS NULL;
Sorting and limiting results
ORDER BY sorts results. ASC is ascending and DESC is descending. To return only a small number of rows, use the syntax appropriate to your database, such as LIMIT, TOP, or a standard offset/fetch form.
SELECT name, price
FROM products
ORDER BY price DESC
LIMIT 10;
SQL Functions and Expressions
An expression calculates a value. A scalar function transforms or examines values in each row, while an aggregate function summarizes values from multiple rows.
| Function category | Representative functions | Purpose | Example use |
|---|---|---|---|
| Text | UPPER, LOWER, TRIM, CONCAT | Change or combine text. | UPPER(name) |
| Numeric | ROUND, ABS, CEILING | Round or calculate numbers. | ROUND(price, 2) |
| Date/time | Current-date functions and date extraction functions | Read or calculate dates and times. | Filter recent orders. |
| Null handling | COALESCE, product-specific null functions | Choose a fallback for missing values. | COALESCE(phone, 'Not provided') |
| Aggregate | COUNT, SUM, AVG, MIN, MAX | Produce one summary value from multiple rows. | SUM(total_amount) |
Functions and expressions can appear in SELECT, WHERE, ORDER BY, and, where appropriate, UPDATE.
SELECT UPPER(name) AS display_name,
ROUND(price * 1.10, 2) AS price_with_tax
FROM products
WHERE COALESCE(discontinued, FALSE) = FALSE
ORDER BY price_with_tax DESC;
Function names and date operations vary between database products. Check the documentation for the selected RDBMS when a function is unavailable.
Grouping and Summarizing Data
GROUP BY divides rows into groups, usually by a category. Aggregate functions then calculate a result for each group.
SELECT customer_id,
COUNT(*) AS order_count,
SUM(total_amount) AS total_sales,
AVG(total_amount) AS average_order
FROM orders
GROUP BY customer_id;
WHERE filters individual rows before grouping. HAVING filters groups after aggregation.
SELECT customer_id, COUNT(*) AS order_count
FROM orders
WHERE status = 'paid'
GROUP BY customer_id
HAVING COUNT(*) >= 3;
When grouping, every selected expression generally must either be an aggregate or be included in GROUP BY. This rule prevents ambiguous results. COUNT(*) counts rows; COUNT(column_name) usually excludes NULL values.
Adding Data with INSERT
Use INSERT INTO to add rows. Always specify the target columns explicitly. This protects your statement if the table's column order changes and makes the values easier to review.
INSERT INTO customers (name, email, phone)
VALUES ('Avery Lee', 'avery@example.test', NULL);
Multiple-row insertion is supported by many systems:
INSERT INTO products (name, price)
VALUES ('USB cable', 8.50),
('Desk lamp', 24.99);
Leave out columns that have a DEFAULT value or a generated identifier. The database may generate a primary-key value automatically. Use NULL for a missing value only when the column allows it; do not put the word NULL in quotes.
Changing Data with UPDATE
UPDATE changes one or more columns in existing rows.
UPDATE products
SET price = ROUND(price * 1.05, 2)
WHERE product_id = 42;
The WHERE clause is essential. Without it, every row may be changed. Before executing an update, run a SELECT with the same condition and inspect the rows.
SELECT product_id, price
FROM products
WHERE product_id = 42;
Expressions and functions can calculate new values, for example SET name = TRIM(name). Confirm the affected-row count and query the rows again after the change.
Removing Data with DELETE
DELETE removes selected rows while leaving the table structure in place.
SELECT *
FROM customers
WHERE email LIKE '%@example.test';
DELETE FROM customers
WHERE email LIKE '%@example.test';
Never omit WHERE unless you intentionally want to remove every row. Removing all rows is different from dropping a table: DELETE FROM table_name; removes records, while DROP TABLE table_name; removes the table definition and its data. Dropping a table is a schema operation and is usually far more destructive.
Table Design Basics
CREATE TABLE defines columns, data types, and constraints.
CREATE TABLE customers (
customer_id INTEGER PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) UNIQUE,
created_at DATE DEFAULT CURRENT_DATE
);
- Primary key: uniquely identifies each row. It may consist of one column or several columns.
- Unique: prevents duplicate values in a column or column combination.
- Foreign key: references a key in another table and represents a relationship.
- NOT NULL: requires a value.
- DEFAULT: supplies a value when an insert does not provide one.
- CHECK: requires a condition, such as
price >= 0, where supported.
Use ALTER TABLE for simple schema changes, such as adding a column:
ALTER TABLE customers
ADD COLUMN phone VARCHAR(30);
Before changing a shared schema, check its dependencies, test the change, and plan how existing rows will receive valid values.
Relationships and JOINs
Tables are related through keys rather than by repeating all information in every row.
- One-to-one: one row in one table corresponds to one row in another, such as a person and one profile.
- One-to-many: one customer can have many orders. The order table stores the customer's foreign key.
- Many-to-many: many students can take many courses. A linking table stores one row for each student-course pairing.
A primary key identifies a row in its own table. A foreign key stores a value that references a primary key or another unique key in a related table.
INNER JOIN
INNER JOIN returns rows for which the join condition matches in both tables.
SELECT o.order_id,
o.order_date,
c.name AS customer_name
FROM orders AS o
INNER JOIN customers AS c
ON o.customer_id = c.customer_id;
The ON condition should join the intended key columns. If a one-to-many relationship is joined, one customer can correctly appear on several result rows—this is not necessarily duplication.
LEFT JOIN
LEFT JOIN keeps every row from the table on the left and adds matching values from the right. If there is no match, right-side columns are NULL.
SELECT c.customer_id, c.name, o.order_id
FROM customers AS c
LEFT JOIN orders AS o
ON o.customer_id = c.customer_id;
This is useful for finding customers who have no orders. A missing or incorrect join condition can create an accidental cross product, in which every row from one table combines with every row from another. Always write and review the ON condition.
| Join type | Rows returned | Typical use case |
|---|---|---|
| INNER JOIN | Only rows matching on both sides. | Orders with a known customer. |
| LEFT JOIN | All left rows, plus matching right rows or NULLs. | All customers, including those without orders. |
Safe Data Manipulation Practices
SQL can change thousands of records with one statement. Treat every UPDATE, DELETE, and schema change as a potentially irreversible operation.
- Use sample or development data while learning.
- Back up important data before destructive or broad changes.
- Write a precise
WHEREclause. - Run the same condition as a
SELECTfirst. - Check the expected row count before executing the modification.
- Use a transaction where supported: begin the work, inspect it, then
COMMITorROLLBACK. - Confirm the final data after committing.
BEGIN;
UPDATE products
SET price = ROUND(price * 1.05, 2)
WHERE product_id = 42;
-- Inspect the result, then choose one:
COMMIT;
-- or ROLLBACK;
Transaction behavior differs by database and client. Some clients automatically commit statements, and some schema operations cannot be rolled back in every system. Understand the behavior before relying on rollback.
| Operation | Risk | Pre-check | Recovery approach |
|---|---|---|---|
| INSERT | Incorrect or duplicate records. | Check required columns, constraints, and existing keys. | Delete the inserted test rows or restore from a backup. |
| UPDATE | Too many rows receive incorrect values. | Run a matching SELECT and inspect the count. | ROLLBACK if uncommitted; otherwise restore or apply a verified correction. |
| DELETE | Rows are removed permanently. | Run the exact deletion condition as a SELECT. | ROLLBACK if available; otherwise restore from a backup. |
| ALTER or DROP | Schema or dependent data may become unavailable. | Review dependencies and test on a copy. | Restore the schema and data from a tested backup. |
Troubleshooting SQL and Connections
A query returns no rows
- The filter may not match the stored spelling, case, date, or format.
- A comparison with NULL may be using
=instead ofIS NULL. - A join may reference the wrong key or eliminate unmatched rows through an inner join.
- Inspect sample rows with a simpler
SELECT, remove filters one at a time, and validate join values.
An UPDATE or DELETE changed too many rows
- The
WHEREclause may be missing or too broad. ANDandORmay be grouped differently than intended.- Use parentheses, run the condition as a
SELECT, and roll back uncommitted work when possible. If committed, use a backup or carefully verified corrective statement.
A join creates duplicate-looking rows
- The relationship may legitimately be one-to-many.
- The join may use a non-unique or incorrect column.
- A join condition may be missing.
- Check primary and foreign keys and the relationship's cardinality. Use aggregation or
DISTINCTonly when it represents the intended result, not merely to hide a faulty join.
A database connection fails
- Verify the host, port, database name, username, password, and authentication method.
- Confirm that the database service is running.
- Check network reachability, firewall rules, permitted ports, and account permissions.
A syntax or unknown-column error appears
- Check spelling and the table definition.
- Look for a missing comma, quote, parenthesis, or delimiter.
- Confirm that the syntax belongs to your database product; limiting and date syntax often differs.
- Avoid reserved words as identifiers, or use the product's correct identifier-delimiting rules.
Core Skills to Practise
- Retrieve customer names and email addresses with
SELECT. - Find orders in a date range and sort them from newest to oldest.
- Search for product names containing a word with
LIKE. - Count orders and calculate sales by customer with
COUNT,SUM,GROUP BY, andHAVING. - Add a customer with an explicit column list and appropriate defaults or NULL values.
- Change one identified product price after previewing the target row.
- Remove only test records after verifying the deletion query.
- List orders with their customers using primary keys, foreign keys, and
INNER JOIN.
Next SQL Topics
After mastering these fundamentals, continue with database administration, normalization, indexes and query performance, advanced joins and subqueries, views, stored procedures, database security and permissions, transaction concurrency, backup and recovery, and using SQL from application programming languages.
Use this SQL online course as a structured reference while practising against a disposable database. Always adapt data types, functions, connection settings, and row-limiting syntax to the RDBMS you selected.