How SQL Queries Work
SQL (Structured Query Language) retrieves, inserts, updates, and deletes data in databases. Understanding the basics helps you write effective queries.
Databases, Tables, and Rows
Section titled “Databases, Tables, and Rows”A database is a collection of organized data. Inside it are tables (like spreadsheets), and inside tables are rows (records) and columns (fields).
Database: purple_hrm ├─ Table: employees │ ├─ Columns: employee_id, first_name, last_name, salary, ... │ └─ Rows: (101, John, Smith, 50000), (102, Jane, Doe, 55000), ... ├─ Table: departments │ ├─ Columns: department_id, department_name, ... │ └─ Rows: (10, Sales), (20, Engineering), ... └─ Table: jobs ├─ Columns: job_id, job_title, min_salary, max_salary └─ Rows: ...The Basic Query Structure
Section titled “The Basic Query Structure”Most queries follow this pattern:
SELECT (which columns?)FROM (which table?)WHERE (which rows?)ORDER BY (sort how?)You’re asking: “Get me these columns from this table, but only rows that match these conditions, sorted like this.”
SELECT: Retrieving Data
Section titled “SELECT: Retrieving Data”SELECT specifies which columns you want to see.
SELECT first_name, last_nameFROM employeesThis retrieves only the first and last names. You could also use SELECT * to get all columns.
WHERE: Filtering Rows
Section titled “WHERE: Filtering Rows”WHERE narrows results to rows matching your conditions.
SELECT first_name, last_name, salaryFROM employeesWHERE salary > 50000This returns employees earning more than 50,000. Without WHERE, you get all rows.
Joining Tables: Combining Data
Section titled “Joining Tables: Combining Data”Tables are related. An employee belongs to a department. A department is in a location. JOIN connects these tables.
SELECT e.first_name, d.department_nameFROM employees eJOIN departments d ON e.department_id = d.department_idThe ON clause specifies how tables connect (matching column values).
Without JOIN, you’d have no way to see which department each employee works in—the tables would be separate.
Aggregating Data: Summarizing
Section titled “Aggregating Data: Summarizing”Sometimes you don’t want individual rows—you want summaries: “How many employees?”, “What’s the average salary?”, “Which product sold most?”
SELECT COUNT(*) as total_employeesFROM employeesCOUNT(*) counts all rows. Other aggregation functions include SUM(), AVG(), MIN(), MAX().
Grouping: Organizing Aggregates
Section titled “Grouping: Organizing Aggregates”GROUP BY combines related rows before aggregating.
SELECT department_id, COUNT(*) as employee_countFROM employeesGROUP BY department_idThis counts employees per department. Without GROUP BY, you’d get one total count for the entire company.
Data Types: What Kind of Value?
Section titled “Data Types: What Kind of Value?”Every column stores a specific type of data:
- VARCHAR(50) = Text up to 50 characters
- INT = Whole numbers
- DECIMAL(10,2) = Numbers with decimals (10 total digits, 2 after decimal)
- DATE = Dates
- CHAR(2) = Fixed-length text (always 2 characters)
Types ensure data integrity and enable proper comparisons.
Keys and Relationships: Connecting Tables
Section titled “Keys and Relationships: Connecting Tables”Primary Key uniquely identifies each row. No two rows have the same primary key.
employee_id INT PRIMARY KEYForeign Key links to another table’s primary key.
FOREIGN KEY (department_id) REFERENCES departments(department_id)Foreign keys enforce relationships. You can’t create an employee record in a department that doesn’t exist.
NULL Values: Missing Data
Section titled “NULL Values: Missing Data”A column might have no value. SQL calls this NULL. It’s not zero or empty string—it’s “unknown” or “missing.”
WHERE outservice_date IS NULL # Has no valueWHERE outservice_date IS NOT NULL # Has a valueNULL is tricky. NULL = NULL returns false (unknown equals unknown?). Always use IS NULL or IS NOT NULL.
INSERT: Adding Data
Section titled “INSERT: Adding Data”INSERT adds new rows.
INSERT INTO employees (first_name, last_name, salary)VALUES ('Alice', 'Johnson', 60000)Column order and value order must match. All required columns must have values.
UPDATE: Changing Data
Section titled “UPDATE: Changing Data”UPDATE modifies existing rows.
UPDATE employeesSET salary = 62000WHERE employee_id = 101Always include a WHERE clause to specify which rows to change. Without it, every row updates.
DELETE: Removing Data
Section titled “DELETE: Removing Data”DELETE removes rows.
DELETE FROM employeesWHERE employee_id = 101Like UPDATE, always use WHERE or you’ll delete everything.
Indexes: Making Queries Fast
Section titled “Indexes: Making Queries Fast”Indexes help databases find data quickly. Without indexes, the database must scan every row. With an index on employee_id, lookups are instant.
You rarely create indexes manually—the database does it, but it’s good to know they exist.
Constraints: Rules for Data
Section titled “Constraints: Rules for Data”Constraints enforce data quality:
NOT NULL # Column must have a valueUNIQUE # No duplicatesPRIMARY KEY # Unique and not nullFOREIGN KEY # Must reference another tableCHECK (age >= 0) # Value must meet conditionDEFAULT 'Unknown' # Use this if no value providedConstraints prevent bad data from entering the database.
Aliases: Shorthand Names
Section titled “Aliases: Shorthand Names”Aliases give tables and columns shorter names for easier reading.
SELECT e.first_name, d.department_nameFROM employees eJOIN departments d ON e.department_id = d.department_ide is an alias for employees, d for departments. Instead of typing employees.first_name, you use e.first_name.
Query Execution Order
Section titled “Query Execution Order”SQL executes queries in a specific order, not necessarily left-to-right:
- FROM - Find the table(s)
- WHERE - Filter rows
- GROUP BY - Organize rows
- SELECT - Choose columns
- ORDER BY - Sort results
Understanding this order helps explain why some queries fail or return unexpected results.