MySQL Notes by SHUMAILA
MySQL Notes by SHUMAILA
Step 2: Install MySQL Server Make sure to replace 'password' with a secure password of your choice in
production environments.
sudo apt install mysql-server
sudo mysql_secure_installation
sudo mysql
EXIT;
Step 2: Create a Table
Getting Started with MySQL Now we’ll create a simple users table:
date_of_birth DATE,
Think of it like:
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
• Folder analogy: );
• Excel analogy:
Step 3: Drop the Database
• A database is like an Excel workbook.
You can delete the entire database (and all its tables) using:
• Each table is a separate sheet inside that workbook.
• Each row in the table is like a row in Excel.
DROP DATABASE startersql;
Renaming a Table
To rename an existing table:
To rename it back:
ALTER TABLE users MODIFY COLUMN name VARCHAR(150); INSERT INTO users VALUES
(1, 'Alice', '[email protected]', 'Female', '1995-05-14', DEFAULT);
Not recommended if your table structure might change (e.g., new columns
added later).
Move a Column to the First Position
To move a column (e.g., email ) to the first position:
This method is safer and more readable. You only insert into specific columns.
Equal To
Not Equal To
-- or
IS NULL
AND / OR
SELECT * FROM users WHERE date_of_birth IS NULL;
SELECT * FROM users WHERE gender = 'Female' AND date_of_birth > '1990-01-01';
IS NOT NULL SELECT * FROM users WHERE gender = 'Male' OR gender = 'Other';
ORDER BY
BETWEEN SELECT * FROM users ORDER BY date_of_birth ASC;
LIMIT
SELECT * FROM users LIMIT 5, 10; -- Get 10 rows starting from the 6th row (Same as
above)
SELECT * FROM users WHERE salary > 60000 ORDER BY created_at DESC LIMIT 5; Basic Syntax
UPDATE table_name
SELECT * FROM users ORDER BY salary DESC;
SET column1 = value1, column2 = value2
WHERE condition;
SELECT * FROM users WHERE salary BETWEEN 50000 AND 70000;
UPDATE users
SET name = 'Alicia'
WHERE id = 1;
UPDATE users
UPDATE users
SET gender = 'Other';
This updates every row in the table. Be very careful when omitting the WHERE 4. Set the gender of user Ishaan to Other .
clause.
UPDATE users
SET gender = 'Other'
WHERE id = 5; Note: This query will overwrite salary for every user. Use with caution!
UPDATE users
SET name = 'Aisha Khan'
UPDATE users
WHERE condition;
• Always back up important data before performing destructive operations.
Example: Delete One Row Quick Quiz: Practice Your DELETE Skills
WHERE id = 3;
DELETE FROM users
);
Constraints in MySQL are rules applied to table columns to ensure the accuracy,
validity, and integrity of the data.
Change an existing column to NOT NULL:
);
3. CHECK Constraint
Add UNIQUE using ALTER TABLE :
Ensures that values in a column satisfy a specific condition.
ADD CONSTRAINT unique_email UNIQUE (email); Example: Allow only dates of birth after Jan 1, 2000
2. NOT NULL Constraint Naming the constraint ( chk_dob ) helps if you want to drop it later.
4. DEFAULT Constraint
); );
Constraint Purpose
);
6. AUTO_INCREMENT
SQL functions help you analyze, transform, or summarize data in your tables.
1. Aggregate Functions
These return a single value from a set of rows.
GROUP BY gender;
2. String Functions
LENGTH()
MIN() and MAX()
Length of user names:
Get the minimum and maximum salary:
Convert names to lowercase or uppercase: Find number of days between today and birthdate:
SELECT name, LOWER(name) AS lowercase_name FROM users; SELECT name, DATEDIFF(CURDATE(), date_of_birth) AS days_lived FROM users;
TIMESTAMPDIFF()
CONCAT()
Calculate age in years:
Combine name and email:
SELECT name, TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) AS age FROM users;
4. Mathematical Functions
3. Date Functions
ROUND() , FLOOR() , CEIL()
NOW()
SELECT salary,
Current date and time: ROUND(salary) AS rounded,
FLOOR(salary) AS floored,
FROM users;
IF()
MySQL Transactions and AutoCommit
SELECT name, gender,
IF(gender = 'Female', 'Yes', 'No') AS is_female By default, MySQL operates in AutoCommit mode. This means that every SQL
FROM users; statement is treated as a transaction and is committed automatically. However, for
more control over when changes are saved, you can turn AutoCommit off and
manage transactions manually.
Summary Table
1. Disabling AutoCommit
Function Purpose
When AutoCommit is off, you can explicitly control when to commit or rollback
COUNT() Count rows changes.
YEAR() / DATEDIFF() Date breakdown / age Important: Until you execute a COMMIT , your changes are not permanent.
To commit a transaction:
COMMIT;
This saves all the changes made since the last COMMIT or ROLLBACK . After this
ROLLBACK;
point, the changes become permanent.
3. ROLLBACK — Revert Changes to the Last Safe Point 4. Enabling AutoCommit Again
If you make an error or decide you don’t want to save your changes, you can
If you want to turn AutoCommit back on (so that every statement is automatically
rollback the transaction to its previous state.
committed), you can do so with:
ROLLBACK;
Here’s a simple example of using COMMIT and ROLLBACK in a transaction: • Consider disabling AutoCommit when performing complex updates to avoid
saving partial or incorrect data.
1. Turn off AutoCommit:
SET autocommit = 0;
COMMIT;
Must be
Yes Yes
unique
Understanding PRIMARY KEY in MySQL
Allows NULL Yes (one or more NULLs
No
A PRIMARY KEY is a constraint in SQL that uniquely identifies each row in a table. values allowed)
• Must be unique
• Cannot be NULL
• Is used to identify rows in a table Example with UNIQUE
• Can be a single column or a combination of columns
CREATE TABLE users (
• Each table can have only one primary key
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(100) UNIQUE,
Example: name VARCHAR(100)
);
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
Auto Increment This is used to maintain data integrity between related data.
In MySQL, a
PRIMARY KEY is often used with the AUTO_INCREMENT attribute to
automatically generate unique values for new rows.
Why Use Foreign Keys?
CREATE TABLE users ( Imagine this scenario:
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) You have a users table. Now you want to store each user’s address. Instead of
); putting address columns inside the users table, you create a separate
addresses table, and link it to users using a foreign key.
This means that every time you insert a new row, MySQL will automatically assign a
unique value to the id column. You can change the starting value of
AUTO_INCREMENT using:
Creating a Table with a Foreign Key
ALTER TABLE users AUTO_INCREMENT = 1000;
Let’s create an addresses table where each address belongs to a user.
street VARCHAR(255),
• Use PRIMARY KEY for the main identifier of a row. city VARCHAR(100),
state VARCHAR(100),
• Use UNIQUE for enforcing non-duplicate values in other columns (like email
pincode VARCHAR(10),
or phone).
FOREIGN KEY (user_id) REFERENCES users(id)
• You can have only one primary key, but you can have many unique );
constraints.
Explanation: Adding ON DELETE Action
• user_id is a foreign key.
By default, if you delete a user that has related addresses, MySQL will throw an
• It references the error. You can control this behavior with ON DELETE .
id column in the table.
users
• This ensures that every address must be linked to a valid user.
Example with ON DELETE CASCADE :
street VARCHAR(255),
CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES users(id) CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
); );
DROP FOREIGN KEY fk_user; ADD CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE
CASCADE;
ALTER TABLE addresses CASCADE Deletes all related rows in child table
ADD CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES users(id);
SET NULL Sets the foreign key to NULL in the child table
users table
id name
1 Aarav
2 Sneha
3 Raj
addresses table
id user_id city
1 1 Mumbai
2 2 Kolkata
3 4 Delhi
1. INNER JOIN
Returns only the matching rows from both tables.
Output:
SELECT users.name, addresses.city
FROM users name city
INNER JOIN addresses ON users.id = addresses.user_id;
Aarav Mumbai
Sneha Kolkata
Output:
Raj NULL
name city
Raj is shown even though he doesn’t have an address.
Aarav Mumbai
Sneha Kolkata
Visual Representation:
Raj is excluded because there is no matching address. Delhi is excluded
users addresses
because its user_id (4) is not in users .
| 1 | | 1 |
Visual Representation: | 2 | | 2 |
| 3 | | |
| 1 | | 1 |
| 2 | | 2 |
| | | |
FROM users
Returns all rows from the left table ( users ), and matching rows from the right
RIGHT JOIN addresses ON users.id = addresses.user_id;
table ( addresses ). If no match is found, NULLs are returned.
Aarav Mumbai
Sneha Kolkata
name city
NULL Delhi
Delhi is shown even though it points to a user_id that doesn’t exist. SQL UNION and UNION ALL
Visual Representation: The UNION operator in SQL is used to combine the result sets of two or more
| 2 | | 2 |
| | | 4 |
Summary Table will then combine the names from both tables using UNION .
INNER JOIN Only matching rows from both tables Step 1: Create the admin_users Table
LEFT JOIN All rows from left table + matching from right
CREATE TABLE admin_users (
RIGHT JOIN All rows from right table + matching from left
id INT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100),
gender ENUM('Male', 'Female', 'Other'),
date_of_birth DATE,
salary INT
);
Step 2: Insert Sample Data into admin_users SELECT name, salary FROM users
UNION
INSERT INTO admin_users (id, name, email, gender, date_of_birth, salary) VALUES SELECT name, salary FROM admin_users;
UNION
Step 3: Use UNION to Combine Data SELECT name, 'Admin' AS role FROM admin_users;
This returns a single list of unique names from both tables. UNION
ORDER BY name;
If you want to keep duplicate names (if any), use UNION ALL .
Rules of UNION
SELECT name FROM users
UNION ALL 1. The number of columns and their data types must match in all SELECT
SELECT name FROM admin_users; statements.
2. UNION removes duplicates by default.
3. UNION ALL keeps duplicates.
You can also select multiple columns as long as both SELECT queries return the
same number of columns with compatible types.
When to Use UNION
• When you have two similar tables (like current and archived data).
• When you need to combine filtered results (e.g., high-salary users from two Self JOIN in MySQL
sources).
• When performing cross-category reporting. A Self JOIN is a regular join, but the table is joined with itself.
This is useful when rows in the same table are related to each other. For example,
when users refer other users, and we store the ID of the person who referred them
Summary in the same users table.
Operator Behavior
This column:
UPDATE users SET referred_by_id = 1 WHERE id IN (2, 3); -- User 1 referred Users 2
and 3
We want to get each user’s name along with the name of the person who referred
them.
SELECT
a.id,
a.name AS user_name,
b.name AS referred_by
FROM users a
INNER JOIN users b ON a.referred_by_id = b.id;
Explanation:
• a refers to the user being queried.
• b refers to the user who referred them.
• LEFT JOIN is used so that users with NULL in referred_by_id are also
included.
Sample Output:
id user_name referred_by
1 Aarav NULL
2 Sneha Aarav
3 Raj Aarav
4 Fatima Sneha
Summary
• Use Self JOIN when you need to join a table with itself.
• In referral-based relationships, store the referrer’s id in the same table.
Demonstrating That a View is Always Up-To-Date
Let’s see what happens when the underlying data changes.
MySQL Views
Step 1: View before update
A view in MySQL is a virtual table based on the result of a SELECT query. It does
SELECT * FROM high_salary_users;
not store data itself — it always reflects the current data in the base tables.
Suppose we want a view that lists all users earning more than ₹70,000. SET salary = 72000
WHERE name = 'Raj';
FROM users
Step 3: Query the view again
WHERE salary > 70000;
SELECT * FROM high_salary_users;
New Output:
2 Sneha 75000
SELECT * FROM high_salary_users;
5 Fatima 80000
This will return all users from the users table where salary is above ₹70,000. 3 Raj 72000
Notice how Raj is now included in the view — without updating the view
itself. That’s because views always reflect live data from the original table.
Dropping a View
To remove a view: MySQL Indexes
DROP VIEW high_salary_users; Indexes in MySQL are used to speed up data retrieval. They work like the index of
a book — helping the database engine find rows faster, especially for searches,
filters, and joins.
Summary
Viewing Indexes on a Table
• Views act like saved SELECT queries
• Views are not duplicated data To see the indexes on a table, use:
• Changes to base tables are reflected automatically
SHOW INDEXES FROM users;
• Great for simplifying complex queries or creating filtered access
This shows all the indexes currently defined on the users table, including the
automatically created primary key index.
Suppose you’re frequently searching users by their email . You can speed this up
If you often query users using both gender and salary , a multi-column index is
more efficient than separate indexes.
Feature Description
This query can take advantage of the combined index on gender and salary . Use when Query performance on large tables is a concern
Explanation:
Example Scenario: Salary Comparison
• The inner query: SELECT id FROM users WHERE salary > 75000 returns a list
Suppose we want to find all users who earn more than the average salary of all of user IDs (referrers) who earn more than ₹75,000.
users. • The outer query selects users whose referred_by_id is in that list.
FROM users;
Explanation:
• The inner query: SELECT AVG(salary) FROM users returns the average salary.
This shows each user’s salary along with the overall average.
Summary
Subquery with IN Returns multiple values specified columns. It is typically used with aggregate functions like COUNT , SUM ,
AVG , MIN , or MAX .
Subquery in SELECT Shows related calculated value
The HAVING clause is used to filter groups after aggregation — similar to how
Subquery in FROM Acts as a virtual table
WHERE filters individual rows.
FROM users
GROUP BY gender;
Explanation: Why not WHERE ?
• This groups users by gender. • WHERE is used before grouping.
• Then calculates the average salary for each group. • HAVING is used after groups are formed — it’s the only way to filter
aggregated values.
Output:
referred_by_id total_referred
Summary
1 2
2 1 Can use
Clause Purpose
aggregates?
Use
SELECT gender, AVG(salary) AS avg_salary GROUP BY to organize data, and HAVING to filter those groups based on
FROM users aggregate conditions.
GROUP BY gender
HAVING AVG(salary) > 75000;
ROLLUP
To get subtotals and grand totals, you can use ROLLUP :
SELECT gender, COUNT(*) AS total_users
FROM users
But when defining stored procedures, we use ; inside the procedure as well. This
can confuse MySQL. To avoid this, we temporarily change the delimiter (e.g. to
$$ or // ) while creating the procedure.
DELIMITER $$
DELIMITER ;
Example:
IN p_email VARCHAR(100),
IN p_gender ENUM('Male', 'Female', 'Other'),
IN p_dob DATE,
IN p_salary INT
Dropping a Stored Procedure
)
BEGIN
INSERT INTO users (name, email, gender, date_of_birth, salary) DROP PROCEDURE IF EXISTS AddUser;
END$$
DELIMITER ;
Summary
This creates a procedure named AddUser that accepts five input parameters.
Command Purpose
This will insert the new user into the users table.
Step 1: Create the Log Table
Triggers in MySQL CREATE TABLE user_log (
);
Triggers are commonly used for:
• Logging changes
• Enforcing additional business rules
• Automatically updating related data Step 2: Create the Trigger
We now define a trigger that runs after a new user is added.
BEGIN BEGIN
END$$
•
NEW refers to the new row being added to the table.
Scenario: Log Every New User Insertion users
• We insert the new user’s ID and name into the table.
user_log
Suppose we want to log every time a new user is inserted into the users table.
We’ll create a separate table called user_log to store log entries.
Step 3: Test the Trigger
More on MySQL
Now check the user_log table:
This section covers some essential MySQL features and operators that help you
write more powerful and flexible queries.
SELECT * FROM user_log;
BEFORE / AFTER When the trigger runs 2. Add a Column to an Existing Table
INSERT / UPDATE / Use ALTER TABLE to add a column:
What kind of action triggers it
DELETE
FOR EACH ROW Executes for each affected row This adds a new column named city to the users table.
3. Wildcard Operators SELECT DISTINCT gender FROM users;
Wildcards are used with the LIKE operator for pattern matching in text.
Returns a list of unique gender values from the users table.
Wildcard Description Example
Matches any
% WHERE name LIKE 'A%' (starts with A)
sequence
6. TRUNCATE Keyword
Matches a single WHERE name LIKE '_a%' (second letter
_
character TRUNCATE removes all rows from a table, but keeps the table structure.
is ‘a’)
LIMIT 10, 5;
This renames city to location and changes its type.
DISTINCT is used to return only unique values. This changes only the datatype of salary .