| Design Element | What to Decide | Example (students table) |
|---|---|---|
| Data‑type | TEXT, NUMERIC, INTEGER, REAL, DATE, BOOLEAN – choose the smallest type that can hold the data. | studentid INTEGERfirstname TEXT(30)dob DATE |
| Field size & validation | Set length (e.g. TEXT(20)), NOT NULL, UNIQUE, DEFAULT values. | email TEXT(50) NOT NULLstatus TEXT(1) DEFAULT 'A' |
| Primary key | Uniquely identifies each record; usually AUTOINCREMENT. | student_id INTEGER PRIMARY KEY AUTOINCREMENT |
| Foreign key & referential integrity | Links to another table; enforce ON DELETE/UPDATE actions. | classid INTEGER REFERENCES classes(classid) ON DELETE RESTRICT |
| Normalisation (1NF & 2NF) | Eliminate repeating groups and partial dependencies – each field stores one fact only. | Separate students and enrolments tables rather than storing many class codes in one record. |
ORDER BY) and/or grouping (GROUP BY).| Operation | Syntax (expanded) | Typical Use (example) |
|---|---|---|
| Sorting – single or multiple criteria | SELECT … FROM table ORDER BY col1 [ASC|DESC], col2 ASC; | List products by category then by price descending. |
| Searching – exact match | WHERE col = value | Find students whose class_id = 3. |
| Searching – pattern with wild‑cards | WHERE col LIKE 'A%' (starts with A)WHERE col LIKE '%son' (ends with son)WHERE col LIKE '%art%' (contains art) | Names beginning with “Sm”, ending with “son”, or containing “art”. |
| Combined criteria (AND / OR) | WHERE (col1 = 5 OR col1 = 7) AND col2 > 1000 | Students in year 5 or 7 whose score exceeds 1000. |
| Calculated field (nested functions) | SELECT ROUND(price*qty,2) AS Total, UPPER(product_name) AS PName FROM sales; | Shows total with two decimals and product name in uppercase. |
| Aggregate functions | SELECT SUM(col), AVG(col), COUNT(*), MAX(col), MIN(col) FROM …; | Total sales, average salary, number of students, highest mark, lowest price. |
| Grouping | GROUP BY col1 HAVING COUNT(*) > 5 | Regional totals but only for regions with more than five sales. |
| Import / Export | IMPORT FROM 'students.csv' INTO students;EXPORT TO 'sales.txt' FROM sales; | Load a CSV file created in a spreadsheet; save query results for use elsewhere. |
Use AS to give a user‑friendly heading and apply functions before the data is displayed.
SELECT student_id AS "ID",
firstname || ' ' || lastname AS "Student Name",
ROUND(average_mark,1) AS "Avg Mark",
TO_CHAR(dob,'DD/MM/YYYY') AS "Date of Birth"
FROM students;
ROUND(number, d) – round to d decimal places.CAST(number AS MONEY) or printf('£%.2f', number) – add a currency symbol.ROUND(number*100,0) || '%' AS "Result" – display percentages.FORMAT(number,'N0') (where supported) – thousand‑separator commas.TO_CHAR(date,'DD/MM/YYYY') – British date style.UPPER(text), LOWER(text), INITCAP(text) – change case.CONCAT(a,' ',b) or the || operator – build full names or sentences.While most IGCSE work is done in Access or similar tools, the same ideas apply to SQL‑generated reports.
CASE expression to prepend a symbol or colour tag that the report‑viewer recognises.SELECT product_name,
price,
IIF(price > 1000,'*HIGH*','') AS "Flag"
FROM products;
In a printed report the asterisk can be explained in a legend.
Best when several fields are required – each row = a record, each column = a field.
SELECT product_id,
product_name,
price
FROM products
ORDER BY price DESC;
| product_id | product_name | price (£) |
|---|---|---|
| 105 | Smartphone X | 799.99 |
| 112 | Laptop Pro | 1 199.00 |
| 207 | Headphones | 149.95 |
Ideal for a single field – displayed as a simple vertical list.
SELECT DISTINCT city
FROM customers
ORDER BY city;
Use concatenation to produce a readable sentence for each record.
SELECT CONCAT('Order ', order_id, ': ',
product_name, ' (', quantity, ')') AS "Order Summary"
FROM orders;
SELECT department AS "Dept.",
COUNT(*) AS "No. of Staff",
ROUND(AVG(salary),0) AS "Avg Salary (£)"
FROM staff
GROUP BY department
ORDER BY department;
| Dept. | No. of Staff | Avg Salary (£) |
|---|---|---|
| HR | 8 | 45 200 |
| IT | 12 | 58 750 |
| Sales | 15 | 39 400 |
SELECT firstname || ' ' || lastname AS "Employee Name",
department AS "Dept.",
ROUND(salary,0) AS "Salary (£)",
TO_CHAR(dob,'DD/MM/YYYY') AS "DOB"
FROM staff
ORDER BY department, last_name;
SELECT CONCAT(firstname,' ',lastname,
' – ',department,
' – £',ROUND(salary,0)) AS "Employee Summary"
FROM staff;
SELECT region AS "Region",
'£' || printf('%.2f',SUM(sale_amount)) AS "Total Sales"
FROM sales
GROUP BY region
ORDER BY region;
ORDER BY, WHERE (AND/OR, LIKE), calculated fields, aggregates, GROUP BY, IMPORT/EXPORT.AS with quotes for spaces.UPPER, LOWER, ROUND, CONCAT, TO_CHAR, currency/percentage patterns.CASE or IIF to flag extreme values.Your generous donation helps us continue providing free Cambridge IGCSE & A-Level resources, past papers, syllabus notes, revision questions, and high-quality online tutoring to students across Kenya.