HKDSE ICT|SQL and Database Queries Lesson-Prep Guide (for tutors)|Clause order, WHERE versus HAVING, four joins, GROUP BY and aggregates
- 2026-11-03
Students can write SELECT * FROM student, but the moment GROUP BY appears they scatter columns, and asked the difference between WHERE and HAVING they go quiet. This lesson fixes one clause order and one 120-row table so every query can be checked by arithmetic instead of recalled as a pattern.
01 Prerequisites (3-minute check)
If any of these fails, fix it before the lesson starts.
| Skill | Quick check | Pass mark |
|---|---|---|
| Tables | What does a row and a column each represent? | A row is a record, a column is a field |
| Primary keys | Can two rows share a primary key value? | No, it must be unique |
| Basic SELECT | What does SELECT * mean? | Return every column |
| Comparison operators | How is not-equal written in SQL? | As <> or != |
02 Lesson flow (60 minutes)
| Time | Stage | Tutor does | Student does |
|---|---|---|---|
| 0–6 min | One table, three facts | Fields, records, primary key | Draw the table first |
| 6–16 min | Six clauses in order | 6 clauses, fixed positions | Written order is not run order |
| 16–30 min | WHERE versus HAVING | Filter rows versus filter groups | Aggregate conditions go to HAVING |
| 30–44 min | Aggregates and grouping | 120 / 5 = 24 | Only grouped columns after GROUP BY |
| 44–54 min | Four joins | 4 preserved sides | INNER needs both sides |
| 54–60 min | Check the numbers and exit | Verify with row counts and totals | If it does not add up, it is wrong |
03 Teaching script (read it out)
Scene 1: Draw the table before writing the query
Ask: after GROUP BY class, why is student_name invalid? (Names exist per row, not per group)
Scene 2: Teach written order apart from run order
Ask: does COUNT(*) > 20 belong in WHERE or HAVING? (HAVING)
Scene 3: Finish with arithmetic checking
Ask: why would a join inflate the total? (One-to-many duplication)
04 Question types and worked steps
| Type | Example | Steps | Answer |
|---|---|---|---|
| Single-table filter | SELECT name FROM student WHERE form = ‘S6’ | Choose columns, name the table, add the condition, quote strings | Only matching rows return |
| Aggregate and group | Class size and mean mark per class | SELECT class, COUNT(*), AVG(mark) … GROUP BY class | Five groups of 24 |
| Filter after grouping | Classes with a mean above 60 | Write the aggregate condition in HAVING, never WHERE | HAVING AVG(mark) > 60 |
| Join two tables | Get the form tutor from the class table | Write the ON condition and name the preserved side | INNER keeps only matches |
05 Independent practice (3 questions)
| Question | Answer | What to watch |
|---|---|---|
| Write: classes with a mean above 65, with size | SELECT class, COUNT(*) FROM student GROUP BY class HAVING AVG(mark) > 65; | The aggregate condition belongs in HAVING |
| Judge: is WHERE COUNT(*) > 10 valid? | No | WHERE runs before grouping, so COUNT does not exist yet |
| Calculate: a join returns 240 rows instead of 120, why? | A one-to-many relationship duplicated rows | Use DISTINCT or aggregate first |
06 Common mistakes and what to say
| Mistake | Student writes | Say this |
|---|---|---|
| Aggregate inside WHERE | A student writes WHERE COUNT(*) > 20 | Tutor line: “WHERE runs while rows still exist and no groups do, so COUNT is not there yet. Counting groups is HAVING.” |
| Per-row column after GROUP BY | A student writes SELECT name, class, COUNT(*) … GROUP BY class | Tutor line: “After grouping there is one row per class. Which name would it print? Names only exist per row.” |
| Join without ON | A student writes FROM student JOIN class | Tutor line: “Without ON the engine pairs every row with every row. The row count explodes and the answer cannot be right.” |
| Confusing COUNT(column) with COUNT(*) | A student counts people with COUNT(phone) and gets fewer | Tutor line: “COUNT(column) skips NULL, so anyone without a phone vanishes. Count people with COUNT(*).” |
07 Homework (paper, section and question numbers)
- Secondary ICT chapter index — Review the database chapters and copy the fixed clause order
- S5 ICT: system development life cycle — Use the requirements step there to list the fields a student table needs
- Secondary Maths chapter index — Use the statistics chapter to recheck the mean calculation on this page
08 Exit check (last 5 minutes)
| Question | Answer | Decision |
|---|---|---|
| Which clause holds an aggregate condition? | HAVING | Answering WHERE means execution order is missing |
| What may be selected after GROUP BY? | Grouped columns and aggregates | Answering any column confuses rows with groups |
| Which rows does INNER JOIN keep? | Only rows matched on both sides | Answering all rows means the preserved side is unclear |
09 Tutor FAQ
Which year group?
S6 ICT databases; S5 can start with single-table SELECT in the summer term.
How much syntax must be memorised?
Six clause positions and four aggregates; the rest follows from execution order.
Are answers provided?
Three practice items with answers and explanations, plus three linked chapters.
Find a tutor — freeTutor Registration →
A TutorZone lesson-prep guide. Written by the TutorZone team; questions and lesson flow are original and are not taken from any school or publisher material.


