SQL for Absolute Beginners

A guide with detailed explanations and engaging examples to help you learn SQL

Getting Started

SQL (Structured Query Language) is used to interact with relational databases. To start practicing SQL, install a database system such as MySQL, PostgreSQL, or SQLite. You can also try free online platforms like SQLZoo or Mode Analytics.

Once you have a database installed, you can execute queries using a command-line tool or a graphical interface. For example, in a MySQL terminal you might type:

mysql -u username -p

After connecting, you'll be ready to write and run SQL commands.

What is SQL?

SQL is the standard language for managing and manipulating relational databases. It allows you to create databases, query data, update records, and control access to your data. Whether you’re analyzing data or building database-driven applications, SQL is an essential skill.

Basic Syntax

A basic SQL query typically starts with the SELECT statement, followed by the columns you want to retrieve, and the FROM clause to specify the table.

SELECT column1, column2
FROM table_name;

For example, to get the names and emails from a users table:

SELECT name, email
FROM users;

This query fetches the name and email columns from the users table.

Data Types

When designing tables, you must choose the right data types for your columns. Common SQL data types include:

  • INT: For whole numbers.
  • VARCHAR: For variable-length text.
  • DATE: For dates.
  • DECIMAL: For exact numeric values with decimals.

Choosing the correct data type ensures efficient storage and accurate data processing.

Creating Tables

Use the CREATE TABLE statement to define a new table and its columns, along with data types and constraints.

CREATE TABLE users (
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(100),
  email VARCHAR(100) UNIQUE,
  created_at DATE
);

This command creates a table named users with columns for user ID, name, email, and creation date.

Inserting Data

The INSERT INTO statement adds new rows to a table.

INSERT INTO users (name, email, created_at)
VALUES ('Alice', 'alice@example.com', '2025-04-16');

This statement inserts a new user into the users table with a name, email, and creation date.

Retrieving Data

The SELECT statement is the foundation for querying data in SQL. Below are multiple examples that demonstrate a variety of techniques, each explained in detail.

Example 1: Basic SELECT
SELECT * FROM users;

This query retrieves all columns and every row from the users table. The asterisk (*) serves as a wildcard, which means "all columns."

Example 2: Selecting Specific Columns
SELECT name, email FROM users;

This query returns only the name and email columns from the users table, helping to reduce unnecessary data and improve query efficiency.

Example 3: Filtering Data with WHERE
SELECT * FROM users
WHERE age >= 18;

The WHERE clause filters rows according to the specified condition. In this example, it retrieves only those users aged 18 or older.

Example 4: Pattern Matching with LIKE
SELECT name, email FROM users
WHERE email LIKE '%@example.com';

The LIKE operator is used for pattern matching. Here, the percent sign (%) acts as a wildcard. This query returns rows where the email ends with "@example.com."

Example 5: Combining Conditions with AND/OR
SELECT name, email FROM users
WHERE age >= 18 AND country = 'USA';

This query uses the AND operator to return users who are at least 18 years old and are located in the USA. You can also use OR to broaden the conditions.

Example 6: Sorting Data with ORDER BY
SELECT name, email FROM users
ORDER BY name ASC, age DESC;

The ORDER BY clause sorts the results by one or more columns. Here, the rows are ordered by name in ascending order; if names are identical, the rows are sorted by age in descending order.

Example 7: Removing Duplicates with DISTINCT
SELECT DISTINCT country FROM users;

The DISTINCT keyword removes duplicate values from the result set, ensuring that each country appears only once.

Example 8: Limiting the Results with LIMIT
SELECT * FROM users
LIMIT 5;

The LIMIT clause restricts the number of rows returned. This query returns only the first 5 rows from the users table.

Example 9: LIMIT with OFFSET
SELECT * FROM users
LIMIT 5 OFFSET 10;

Here, LIMIT 5 OFFSET 10 skips the first 10 rows and returns the next 5 rows. This is useful for implementing pagination.

Example 10: Grouping Data with GROUP BY
SELECT country, COUNT(*) AS user_count
FROM users
GROUP BY country;

The GROUP BY clause groups rows by the specified column. This query calculates the number of users in each country using the COUNT() function.

Example 11: Filtering Groups with HAVING
SELECT country, COUNT(*) AS user_count
FROM users
GROUP BY country
HAVING COUNT(*) > 10;

The HAVING clause filters the results after grouping. This query returns only those groups where the number of users is greater than 10.

Example 12: Using a Subquery
SELECT name, email
FROM users
WHERE id IN (
  SELECT user_id FROM orders WHERE total > 100
);

This query employs a subquery to select users who have placed orders exceeding 100. The inner query retrieves user_id values from the orders table, and the outer query fetches the corresponding name and email.

Example 13: Using SQL Functions
SELECT UPPER(name) AS upper_name, LENGTH(name) AS name_length
FROM users;

This query uses UPPER() to convert names to uppercase and LENGTH() to calculate the character count of each name. Aliases (AS upper_name, AS name_length) are used to label the results.

Example 14: Combining Results with UNION
SELECT name, email FROM users
WHERE country = 'USA'
UNION
SELECT name, email FROM users
WHERE country = 'Canada';

The UNION operator combines the results of two SELECT statements into a single result set. In this example, it returns users from both the USA and Canada. Note that UNION removes duplicates by default.

Example 15: Using CASE in a Query
SELECT name,
  CASE 
    WHEN age >= 18 THEN 'Adult'
    ELSE 'Minor'
  END AS age_group
FROM users;

This query uses a CASE expression to create a new column called age_group that categorizes users as 'Adult' or 'Minor' based on their age. CASE expressions are useful for conditional logic directly within your SELECT statements.

These examples showcase a wide range of techniques to retrieve and manipulate data using SQL. Experiment with these queries on your own database to build confidence in data extraction and transformation.

Updating & Deleting Data

Modify existing data using UPDATE and remove data using DELETE.

-- Update a user's email
UPDATE users
SET email = 'alice_new@example.com'
WHERE name = 'Alice';

-- Delete a user record
DELETE FROM users
WHERE id = 10;

These commands let you change or remove data from the table as needed.

Joins

Joins combine rows from two or more tables based on related columns. Common joins include INNER JOIN, LEFT JOIN, and RIGHT JOIN.

SELECT orders.id, users.name, orders.total
FROM orders
INNER JOIN users ON orders.user_id = users.id;

This example retrieves order information along with the corresponding user's name using an inner join.

Aggregation

Aggregate functions allow you to perform calculations on a set of values. Common functions include COUNT, SUM, AVG, MIN, and MAX.

SELECT COUNT(*) AS total_users, AVG(age) AS average_age
FROM users;

This query calculates the total number of users and the average age.

Subqueries

Subqueries are queries nested within another SQL query. They can be used in SELECT, INSERT, UPDATE, or DELETE statements.

SELECT name, email
FROM users
WHERE id IN (SELECT user_id FROM orders WHERE total > 100);

This query selects users who have orders over 100 in value.

Views & Stored Procedures

Views are virtual tables based on a SELECT query, and stored procedures are saved SQL code that can be executed on demand.

-- Create a view
CREATE VIEW active_users AS
SELECT * FROM users
WHERE active = 1;

-- Create a stored procedure (MySQL syntax)
DELIMITER $$
CREATE PROCEDURE GetUserCount()
BEGIN
  SELECT COUNT(*) FROM users;
END$$
DELIMITER ;

These features help encapsulate complex queries and operations.

Security & Permissions

Database security is crucial. Use user roles and permissions to control access to your data. Ensure you use parameterized queries or prepared statements to protect against SQL injection.

-- Granting SELECT privilege on a table
GRANT SELECT ON database_name.users TO 'username'@'localhost';

Proper security practices help maintain the integrity and confidentiality of your data.

What's Next?

Congratulations on completing this comprehensive SQL guide! You now have a solid foundation in querying and managing databases. The next steps are to build projects, explore advanced optimization techniques, and dive deeper into database design and management.

For further exploration, check out these resources: