SQL Foundations: The Complete Beginner's Guide
Everything you need to go from zero to confident with SQL — from understanding what a database is to writing real queries with SELECT, WHERE, JOINs, functions, and more. Oracle, MySQL, and PostgreSQL covered.
What is SQL? The Language of Databases
SQL (Structured Query Language) is the standard language of relational databases. It lets you create, read, update, and manage data in systems like Oracle, MySQL, SQL Server, and PostgreSQL.
Think of SQL as the Google Search of databases — you describe what data you want, and the database engine finds and returns it.
Why SQL matters:
- Data is everywhere — from apps to websites to enterprise systems, everything runs on data stored in relational databases.
- Universal skill — SQL syntax is largely the same across Oracle, MySQL, PostgreSQL, and SQL Server, so learning it once works everywhere.
- Business backbone — organizations rely on SQL for analytics, reporting, transactions, and integrations.
- Career multiplier — SQL consistently ranks as one of the most in-demand technical skills, relevant for developers, analysts, and architects alike.
SQL commands are grouped into categories based on what they do:
| Column | Type | Description |
|---|---|---|
DDL | Data Definition Language | CREATE, ALTER, DROP, TRUNCATE — define and modify database structure |
DML | Data Manipulation Language | INSERT, UPDATE, DELETE — add, change, or remove data |
DQL | Data Query Language | SELECT — retrieve data from tables |
DCL | Data Control Language | GRANT, REVOKE — control permissions |
TCL | Transaction Control Language | COMMIT, ROLLBACK, SAVEPOINT — manage transactions |
SQL is declarative
You tell SQL what you want, not how to get it. The database engine figures out the execution plan. This is what makes SQL so powerful — you write 10 lines and the engine does the work of thousands of procedural operations.
SQL Data Types — Choosing the Right Column Type
When designing a table, the most important decision for each column is its data type. The right type ensures efficient storage, data integrity, and faster queries.
Numeric Types
| Column | Type | Description |
|---|---|---|
INT / INTEGER | Whole number | Employee IDs, quantities, counts. No decimal places. |
SMALLINT | Small integer | Age, status codes. Saves storage for small-range values. |
BIGINT | Large integer | Population figures, auto-increment PKs in large systems. |
DECIMAL(p,s) | Fixed-point | Financial values like salary, price, tax amounts. Use p=precision (total digits), s=scale (decimal places). |
FLOAT / REAL | Approximate decimal | Scientific measurements, ratings. Avoid for money — use DECIMAL instead. |
NUMBER(p,s) | Oracle native | Oracle's general-purpose numeric type. Equivalent to DECIMAL in most contexts. |
Never use FLOAT for money
Floating-point types (FLOAT, REAL, DOUBLE) are approximate by design — they can introduce rounding errors. Always use DECIMAL(10,2) or Oracle's NUMBER(10,2) for monetary values like salaries, prices, or tax amounts.
String / Character Types
| Column | Type | Description |
|---|---|---|
CHAR(n) | Fixed-length string | Country codes, gender flags — values that are always exactly n characters. |
VARCHAR(n) | Variable-length | Names, descriptions — values of varying length up to n characters. |
VARCHAR2(n) | Oracle native VARCHAR | Oracle's preferred variable-length string type. Functionally identical to VARCHAR. |
TEXT / CLOB | Large text | Long descriptions, notes, HTML content. No length limit (CLOB = Character Large Object). |
Date & Time Types
| Column | Type | Description |
|---|---|---|
DATE | Date + time | In Oracle: stores full date and time. In MySQL/PostgreSQL: date only. |
TIMESTAMP | High-precision date+time | Order timestamps, audit logs. Includes fractional seconds. |
TIME | Time only | Store opening/closing hours without a date component. |
INTERVAL | Duration | Differences between dates — useful in Oracle for date arithmetic. |
Oracle DATE includes time — this surprises many developers
In Oracle, a DATE column stores both date and time (down to seconds). If you store SYSDATE in a DATE column, you get the time too. Always use TRUNC(date_col) when you want to compare dates without the time component, otherwise your WHERE clause will miss rows.
Other Important Types
| Column | Type | Description |
|---|---|---|
BOOLEAN | True/False | MySQL and PostgreSQL native. Oracle uses NUMBER(1) or VARCHAR2(1) with Y/N convention. |
BLOB | Binary Large Object | Images, PDFs, binary files stored in the database. |
ROWID | Oracle internal | Oracle's physical row address. Used for ultra-fast single-row lookups. |
DDL — CREATE, ALTER, DROP
DDL (Data Definition Language) commands define and change the structure of your database objects — databases, tables, indexes, and constraints.
CREATE TABLE
CREATE DATABASE (MySQL / PostgreSQL)
ALTER TABLE — Modify Structure
DROP TABLE
TRUNCATE vs DROP
| Column | Type | Description |
|---|---|---|
DROP TABLE | DDL | Yes — all data gone. Yes — table structure gone. Potentially (Oracle recycle bin). |
TRUNCATE TABLE | DDL | Yes — all rows removed instantly. No — table structure stays. Generally no — auto-commits. |
DELETE FROM | DML | Yes — can use WHERE to be selective. No — table structure stays. Yes — can ROLLBACK. |
TRUNCATE cannot be rolled back
TRUNCATE is a DDL operation — it auto-commits. Once you truncate, the data is gone. Use DELETE FROM table_name if you need the ability to roll back. TRUNCATE is much faster than DELETE for clearing entire tables, but it's irreversible without a backup.
DML — INSERT, UPDATE, DELETE
DML (Data Manipulation Language) commands work with the actual data inside tables, not the structure.
INSERT
UPDATE
DELETE
Always use WHERE with UPDATE and DELETE
Missing a WHERE clause on UPDATE or DELETE affects every row in the table. Before running UPDATE or DELETE on production, always run the equivalent SELECT with the same WHERE clause first to verify the affected rows. Then run the DML and review the row count before committing.
The SELECT Statement
SELECT is the most frequently used SQL command. It retrieves data from one or more tables.
SELECT * is fine for exploration, not for production
SELECT * retrieves every column, which is useful when exploring data interactively. In production code, always list the specific columns you need. This avoids breaking if columns are added/renamed and dramatically improves query performance on wide tables.
WHERE Clause — Filtering Rows
The WHERE clause filters which rows are returned. Without it, every row in the table is included.
| Column | Type | Description |
|---|---|---|
= | Equals | WHERE dept = 'IT' |
!= or <> | Not equals | WHERE status != 'I' |
> | Greater than | WHERE salary > 50000 |
>= | Greater than or equal | WHERE hire_date >= DATE '2023-01-01' |
< | Less than | WHERE salary < 100000 |
AND | Both conditions must be true | WHERE dept = 'IT' AND status = 'A' |
OR | Either condition can be true | WHERE dept = 'IT' OR dept = 'HR' |
NOT | Negate a condition | WHERE NOT status = 'I' |
ORDER BY — Sorting Results
ORDER BY sorts the result set. Without it, row order is not guaranteed.
DISTINCT — Removing Duplicates
DISTINCT eliminates duplicate rows from a result set.
DISTINCT operates on the full row
SELECT DISTINCT department, status returns unique combinations of both columns — not just unique departments. Each unique (department, status) pair is one row.
LIKE, IN, and BETWEEN
These three operators are powerful WHERE clause tools for pattern matching, set membership, and range filtering.
LIKE — Pattern Matching
| Column | Type | Description |
|---|---|---|
% | Any sequence | LIKE 'A%' matches Alice, Adam, Anita |
_ | Exactly one character | LIKE '_ita' matches Anita, Smita, Sunita |
IN — Set Membership
BETWEEN — Range Filter
BETWEEN is inclusive on both ends
BETWEEN 50000 AND 80000 includes rows where salary is exactly 50000 or exactly 80000. It is equivalent to salary >= 50000 AND salary = 80000.
NULL Handling — IS NULL & IS NOT NULL
NULL represents a missing or unknown value. It is not the same as zero, an empty string, or the word "NULL". NULL requires special handling in SQL.
You cannot compare NULL with = or !=
This query will never return rows: WHERE email = NULL. NULL is not equal to anything, including itself. You must always use IS NULL or IS NOT NULL. This is one of the most common SQL beginner mistakes.
SQL Operators
SQL has four categories of operators. Understanding them is essential for writing effective WHERE clauses and expressions.
Arithmetic Operators
Comparison Operators
Logical Operators
Concatenation Operator
LIMIT & FETCH FIRST — Row Limiting
Row limiting is used to return only a subset of results — essential for pagination and performance.
Always use ORDER BY with row limiting
Without ORDER BY, the rows returned by LIMIT or FETCH FIRST are non-deterministic — the database can return any rows in any order. For correct pagination, always specify an ORDER BY clause.
Aliases — AS Keyword
Aliases give a column or table a temporary name in the output. They improve readability and are required when referencing calculated columns.
SQL Comments
Comments document your SQL code and are ignored by the database engine during execution.
Good commenting practice
Comment the why, not the what. -- filter active only adds nothing when the code already says WHERE status = 'A'. A better comment would be: -- inactive employees are excluded from payroll calculations per HRMS-101.
Basic Functions — UPPER, ROUND, NOW
SQL has built-in functions for working with strings, numbers, and dates. These cover the vast majority of everyday transformation needs.
String Functions
Numeric Functions
Date Functions
Common Gotchas for Beginners
Important Gotchas
- !
Using = NULL instead of IS NULL.
WHERE email = NULLnever matches any row because NULL is not equal to anything — not even itself. Always writeWHERE email IS NULLorWHERE email IS NOT NULL. - !
Forgetting WHERE on UPDATE or DELETE. Without a WHERE clause,
UPDATE employees SET salary = 0sets every employee's salary to zero. Always verify with a SELECT first. - !
Using FLOAT for currency values. Floating-point arithmetic introduces invisible rounding errors. For prices, salaries, and tax amounts always use
DECIMAL(p,s)orNUMBER(p,s). - !
Assuming ORDER BY without LIMIT is enough. Row order without LIMIT/FETCH FIRST is not guaranteed in SQL — the engine is free to return rows in any order it chooses for performance reasons. Rely on ORDER BY only in the final query that returns data to the user.
- !
Oracle DATE columns storing time. In Oracle, DATE stores date + time. Comparisons like
WHERE order_date = TO_DATE('2025-01-15', 'YYYY-MM-DD')fail if the time is not midnight. UseTRUNC(order_date) = DATE '2025-01-15'ororder_date BETWEEN DATE '2025-01-15' AND DATE '2025-01-15' + 1. - !
AND has higher precedence than OR.
WHERE dept = 'IT' OR dept = 'HR' AND status = 'A'is evaluated asWHERE dept = 'IT' OR (dept = 'HR' AND status = 'A')— which may not be what you intended. Always use parentheses when mixing AND and OR.
Key Takeaways
Key Takeaways
- SQL is the universal language of relational databases. The core syntax works across Oracle, MySQL, PostgreSQL, and SQL Server with minor dialect differences.
- Choose data types carefully at design time — DECIMAL for money, VARCHAR2/VARCHAR for text, DATE/TIMESTAMP for time values. Changing column types later requires a migration.
- DDL (CREATE, ALTER, DROP) defines structure. DML (INSERT, UPDATE, DELETE) manages data. Always use WHERE with UPDATE and DELETE.
- NULL is the absence of a value — it is not zero or empty string. Use IS NULL and IS NOT NULL. Use NVL() or COALESCE() to substitute a default for NULLs in expressions.
- LIKE with % and _ provides pattern matching. IN tests set membership. BETWEEN filters ranges (inclusive on both ends).
- Always ORDER BY when using LIMIT or FETCH FIRST. Row order without ORDER BY is undefined.
- Built-in functions (UPPER, ROUND, TRUNC, SUBSTR, COALESCE, TO_CHAR) handle the vast majority of data transformation needs without writing procedural code.


