Post

Learn SQL - Web Dev Simplified

Learn SQL - Web Dev Simplified

SQL (Structured Query Language) is the standard language for interacting with relational databases. Below is a quick summary based on the Web Dev Simplified SQL tutorial, with short explanations before each code section.

Before diving into the world of SQL, you’ll need a SQL environment. There are many tools available for this. If you prefer a graphical user interface, you might want to try MySQL Workbench.

In my case, I used MySQL and phpMyAdmin installed via docker. I’ve written a post explaining how to set it up, check it out here: Install MySQL and phpMyAdmin using Docker in Ubuntu.

SQL Basics

This section introduces foundational SQL operations to help you create and interact with relational databases. You’ll learn how to create databases and tables, insert and query data, apply filters, join tables, and perform aggregations.

📘 Create & Select a Database

These commands are essential for setting up and switching between databases.

1
2
3
4
5
6
7
8
-- Create a new database
CREATE DATABASE testdb;

-- Delete a database (⚠️ This operation is irreversible)
DROP DATABASE testdb;

-- Select the active database to use
USE testdb;

🧱 Creating Tables

Once your database is created, you can define tables to store structured data. Below is an example for a music catalog containing bands and their albums.

1
2
3
4
5
6
7
8
9
10
11
12
13
-- Create a new database for storing record data
CREATE DATABASE record_company;

-- Create a table to store band information
CREATE TABLE bands (
    id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL,
    PRIMARY KEY (id)
);

-- Add a new column to the bands table (e.g., for country or genre)
ALTER TABLE bands 
ADD added_col VARCHAR(255);
1
2
3
4
5
6
7
8
9
-- Create an albums table with a foreign key linking to bands
CREATE TABLE albums (
    id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL,
    release_year INT,
    band_id INT NOT NULL,
    PRIMARY KEY (id),
    FOREIGN KEY (band_id) REFERENCES bands(id)
);

✍️ Insert & Query Data

Once tables are defined, use INSERT to add data and SELECT to retrieve it.

1
2
3
4
5
6
7
-- Insert a single band into the bands table
INSERT INTO bands (name)
VALUES ('Iron Maiden');

-- Insert multiple bands in a single command
INSERT INTO bands (name)
VALUES ('Deuce'), ('Avenged Sevenfold'), ('Ankor');
1
2
3
4
5
6
7
8
9
10
11
12
-- View all records from the bands table
SELECT * FROM bands;

-- Retrieve only the first two bands
SELECT * FROM bands LIMIT 2;

-- Use aliasing for clearer column names in results
SELECT id AS 'ID', name AS 'Band Name'
FROM bands;

-- Sort bands in descending alphabetical order
SELECT * FROM bands ORDER BY name DESC;
1
2
3
4
5
6
7
8
-- Insert multiple albums referencing band IDs
INSERT INTO albums (name, release_year, band_id)
VALUES 
  ('The Number of the Beasts', 1985, 1),
  ('Power Slave', 1984, 1),
  ('Nightmare', 2018, 2),
  ('Nightmare', 2010, 3),
  ('Test Album', NULL, 3);

🔎 Filtering Data

Use the WHERE clause to filter results based on conditions.

1
2
3
4
5
6
7
-- Retrieve unique album names (no duplicates)
SELECT DISTINCT name FROM albums;

-- Update a specific album's release year
UPDATE albums
SET release_year = 1982
WHERE id = 1;
1
2
3
4
5
6
7
-- Find albums released before the year 2000
SELECT * FROM albums
WHERE release_year < 2000;

-- Filter by partial name or specific band ID
SELECT * FROM albums
WHERE name LIKE '%er%' OR band_id = 2;
1
2
3
4
5
6
7
8
9
10
11
-- Find albums released between two years
SELECT * FROM albums
WHERE release_year BETWEEN 2000 AND 2019;

-- Show albums with unknown release years
SELECT * FROM albums
WHERE release_year IS NULL;

-- Remove entries with missing release years
DELETE FROM albums
WHERE release_year IS NULL;

🔗 Joining Tables

JOIN operations allow you to query related data across multiple tables.

1
2
3
-- Match albums with their corresponding bands
SELECT * FROM bands
JOIN albums ON bands.id = albums.band_id;

Join Types Overview:

  • INNER JOIN: Returns only rows with matching values in both tables.
  • LEFT JOIN: Returns all rows from the left table, with matching rows from the right (if any).
  • RIGHT JOIN: Returns all rows from the right table, with matching rows from the left (if any).

📊 Aggregation & Grouping

Aggregate functions let you summarize and group your data.

1
2
3
4
5
6
7
-- Average release year of all albums
SELECT AVG(release_year) FROM albums;

-- Count how many albums each band has (by band ID)
SELECT band_id, COUNT(*) AS album_count
FROM albums
GROUP BY band_id;
1
2
3
4
5
6
7
8
-- Count albums per band, showing band names instead of IDs
SELECT 
  b.name AS band_name, 
  COUNT(a.id) AS num_albums
FROM bands AS b
LEFT JOIN albums AS a ON a.band_id = b.id
GROUP BY b.id
HAVING num_albums >= 1;

Tip: Use HAVING instead of WHERE when filtering grouped data.

This guide gives you a solid foundation for working with relational databases. As you get comfortable with these commands, you’ll be ready to build more complex queries and applications using SQL.

Exercises

After exploring some basic SQL concepts, this section focuses on a series of exercises primarily proposed by WebDevSimplified. These exercises are designed to be solved after watching the related video or by following along with the previous steps. They are available in his GitHub repository Learn-SQL. In the README.md file, each question is followed by the expected output, you’ll need to figure out the appropriate SQL query to produce that output.

In this post, we share our proposed solutions. First, let’s explore the database schema and set up the environment.

The database contains three tables: bands, albums, and songs. The schema is illustrated in the figure below:

Database Schema

Environment Setup

Make sure you have an environment where you can run SQL queries. As explained earlier, start by creating a database named record_company, then create the schema shown in the figure above.

Once the database is created, insert the required data by running the SQL script provided here.

After completing the setup, you can begin solving the exercises.

  1. Create a songs Table

    1
    2
    3
    4
    5
    6
    7
    8
    
     CREATE TABLE songs (
     id INT NOT NULL AUTO_INCREMENT,
     name VARCHAR(255) NOT NULL,
     length INT NOT NULL,
     album_id INT NOT NULL,
     PRIMARY KEY (id),
     FOREIGN KEY (album_id) REFERENCES albums(id)
     );
    
  2. Select only the Names of all the Bands

    1
    
     SELECT name as "Band Name" FROM bands;
    
    Band Name
    Seventh Wonder
    Metallica
    The Ocean
    Within Temptation
    Death
    Van Canto
    Dream Theater
  3. Select the Oldest Album

    1
    2
    3
    
     SELECT * FROM albums
     WHERE release_year IS NOT NULL
     ORDER BY release_year ASC LIMIT 1;
    
    idnamerelease_yearband_id
    5…And Justice for All19882
  4. Get all Bands that have Albums

    1
    2
    
     SELECT DISTINCT b.name as 'Band Name' FROM bands as b 
     JOIN albums as a ON a.band_id = b.id;
    
    Band Name
    Seventh Wonder
    Metallica
    The Ocean
    Within Temptation
    Death
    Van Canto
  5. Get all Bands that have No Albums

    1
    2
    3
    
     SELECT DISTINCT b.name as 'Band Name' FROM bands as b 
     LEFT OUTER JOIN albums as a ON a.band_id = b.id
     WHERE a.id IS NULL;
    
    Band Name
    Dream Theater
  6. Get the Longest Album

    1
    2
    3
    4
    5
    6
    7
    8
    
     SELECT 
       a.name, 
       a.release_year, 	
       SUM(s.length) AS length 
     FROM albums AS a 
     JOIN songs AS s ON a.id = s.album_id
     GROUP BY a.name, a.release_year
     ORDER BY length DESC LIMIT 1;
    
    NameRelease YearDuration
    Death Magnetic200874.76666593551636
  7. Update the Release Year of the Album with no Release Year

    1
    2
    3
    
     UPDATE albums
     SET release_year = 1986
     WHERE release_year IS NULL;
    
  8. Insert a record for your favorite Band and one of their Albums

    1
    2
    3
    4
    5
    
     INSERT INTO bands (name)
     VALUES ('Favorite Band Name');
    
     INSERT INTO albums (name, release_year, band_id)
     VALUES ('Favorite Album Name', 2000, 8);
    
  9. Delete the Band and Album you added in #8

    1
    2
    3
    4
    5
    
     DELETE FROM albums
     WHERE id = 8;
    
     DELETE FROM bands
     WHERE id = 8;
    
  10. Get the Average Length of all Songs

    1
    
    SELECT AVG(length) as "Average Song Duration" FROM songs; 
    
    Average Song Duration
    5.352472513259112
  11. Select the longest Song off each Album

    1
    2
    3
    4
    5
    6
    7
    
    SELECT 
      a.name AS "Album",
        a.release_year AS "Release Year",
        MAX(s.length) AS "Duration"
    FROM albums AS a 
    JOIN songs AS s ON a.id = s.album_id
    GROUP BY a.name, a.release_year;
    
    AlbumRelease YearDuration
    Tiara20189.5
    The Great Escape201030.2333
    Mercy Falls20089.48333
    Master of Puppets19868.58333
    …And Justice for All19889.81667
    Death Magnetic20089.96667
    Heliocentric20107.48333
    Pelagial20139.28333
    Anthropocentric20109.4
    Resist20185.85
    The Unforgiving20115.66667
    Enter19977.25
    The Sound of Perseverance19988.43333
    Individual Thought Patterns19934.81667
    Human19914.65
    A Storm to Come20065.21667
    Break the Silence20116.15
    Tribe of Force20108.38333
  12. Get the number of Songs for each Band

    1
    2
    3
    4
    5
    6
    7
    
    SELECT
      b.name AS "Band",
      COUNT(s.name) AS "Number of Songs"
    FROM bands as b
    JOIN albums as a ON b.id = a.band_id
    JOIN songs as s ON a.id = s.album_id
    GROUP BY b.name;
    
    BandNumber of Songs
    Seventh Wonder35
    Metallica27
    The Ocean31
    Within Temptation30
    Death27
    Van Canto32
This post is licensed under CC BY 4.0 by the author.

© O so techie. Some rights reserved.

Using the Chirpy theme for Jekyll.