📘 CodingMarble Learn

SQL for Class 12: Build Tables, Ask Questions, Join Tables

SQL is the language used to create and query relational databases. DDL commands (CREATE, ALTER, DROP) build structure; DML commands (INSERT, UPDATE, DELETE) change rows; SELECT reads data. Columns get data types (CHAR, VARCHAR, INT, FLOAT, DATE) and constraints (NOT NULL, UNIQUE, PRIMARY KEY, DEFAULT, FOREIGN KEY). SELECT can use aliases, DISTINCT, WHERE with relational and logical operators, IN, BETWEEN, LIKE and IS NULL, and ORDER BY. Aggregate functions (MAX, MIN, AVG, SUM, COUNT) summarise many rows; GROUP BY makes groups and HAVING filters groups. A Cartesian product pairs every row of one table with every row of another; an equi-join keeps only pairs whose common column matches; a natural join does the same and shows the common column once.

🎬 Step-by-step story

  1. DDL builds the table: CREATE DATABASE, USE, CREATE TABLE with a data type and constraints for each column. ALTER changes it; DROP deletes it.
  2. DML fills and changes rows: INSERT adds, UPDATE edits, DELETE removes. WHERE decides which rows are touched.
  3. SELECT asks questions. WHERE with BETWEEN, IN, LIKE and IS NULL lifts only matching rows. ORDER BY sorts them; DISTINCT removes repeats.
  4. Aggregates squeeze many rows into one number: COUNT, SUM, AVG, MAX, MIN. GROUP BY makes piles by a column; HAVING keeps only piles that pass a test.
  5. Joins combine two tables. The Cartesian product makes every pair. An equi-join keeps only pairs where the common column matches.
  6. Your turn: run a query. Guess which rows light up or what number comes out, then check.

Tip: drag the 3D scene to turn it. Use two fingers to zoom.

🤔 Common doubts, cleared

What is the difference between CHAR and VARCHAR?

CHAR(n) always takes n characters. VARCHAR(n) takes only as many as the value needs, up to n.

What is the difference between DELETE and DROP?

DELETE removes rows but keeps the empty table. DROP removes the table and its structure completely.

Why does WHERE City = NULL return nothing?

NULL means unknown, so = cannot match it. Use IS NULL.

Why can't I write WHERE COUNT(*) > 2?

WHERE works on single rows before groups exist. Use GROUP BY … HAVING COUNT(*) > 2.

Why does the Cartesian product give so many rows?

It pairs every row with every row: rows multiply. Add a join condition to keep only matching pairs.

Equi-join or natural join: which shows the common column once?

Natural join shows it once. Equi-join shows it from both tables.

DDL and DML, and data types

Common MySQL data types

SQL keywords are not case-sensitive; each statement ends with a semicolon. Text and dates go in quotes.

Constraints

A constraint is a rule on a column that stops wrong data.

Working with databases and tables

CREATE DATABASE school;
SHOW DATABASES;
USE school;
CREATE TABLE student (
  RollNo INT PRIMARY KEY,
  Name VARCHAR(20) NOT NULL,
  Class CHAR(3),
  City VARCHAR(15) DEFAULT 'Delhi',
  Marks INT
);
SHOW TABLES;
DESCRIBE student;      -- or DESC student;

ALTER TABLE

ALTER TABLE student ADD Phone CHAR(10);          -- add a column
ALTER TABLE student MODIFY Name VARCHAR(30);     -- change type/size
ALTER TABLE student DROP Phone;                  -- remove a column
ALTER TABLE student ADD PRIMARY KEY (RollNo);    -- add a key (if none)
ALTER TABLE student DROP PRIMARY KEY;            -- remove the key

DROP

DROP TABLE student; removes the table and all its data. DROP DATABASE school; removes the whole database.

Foreign key example: CREATE TABLE marks (ExamID INT PRIMARY KEY, RollNo INT, Score INT, FOREIGN KEY (RollNo) REFERENCES student(RollNo));

INSERT, UPDATE, DELETE

INSERT INTO student VALUES (1, 'Asha', '12A', 'Delhi', 92);
INSERT INTO student (RollNo, Name, Marks) VALUES (2, 'Ravi', 75);  -- City gets DEFAULT, Class NULL
UPDATE student SET Marks = Marks + 5 WHERE Marks < 60;
DELETE FROM student WHERE RollNo = 2;

Without WHERE, UPDATE and DELETE act on every row. DELETE removes rows but keeps the table; DROP removes the table itself.

SELECT: operators, aliases, DISTINCT, WHERE, IN, BETWEEN, LIKE, IS NULL

SELECT * FROM student;
SELECT Name, Marks FROM student;
SELECT Name, Marks + 5 AS NewMarks FROM student;   -- arithmetic + alias
SELECT DISTINCT City FROM student;                  -- no repeats

ORDER BY

SELECT * FROM student ORDER BY Marks DESC;
SELECT * FROM student ORDER BY City, Name;   -- by City, then Name inside each city

ASC (ascending) is the default; DESC sorts high to low.

Aggregate functions

Aggregate (group) functions work on many rows and return one value.

All except COUNT(*) ignore NULL values. Example with Marks 92, 75, 58, NULL: COUNT(*) = 4, COUNT(Marks) = 3, SUM = 225, AVG = 75.

GROUP BY and HAVING

GROUP BY puts rows with the same value in a column into one group, and aggregates run once per group.

SELECT City, COUNT(*), AVG(Marks)
FROM student
GROUP BY City;

HAVING filters groups using an aggregate condition:

SELECT City, COUNT(*) FROM student
GROUP BY City
HAVING COUNT(*) >= 2;

WHERE vs HAVING: WHERE filters rows before grouping and cannot use aggregates; HAVING filters groups after grouping. Order of clauses: SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY. Columns in SELECT that are not aggregated should be in GROUP BY.

Joins: Cartesian product, equi-join, natural join

Tables: STUDENT(RollNo, Name) with 3 rows and MARKS(RollNo, Score) with 2 rows.

Cartesian product

SELECT * FROM student, marks;

Every row of the first table is paired with every row of the second: 3 × 2 = 6 rows. Degree = 2 + 2 = 4 columns. Most pairs are meaningless.

Equi-join

SELECT * FROM student S, marks M
WHERE S.RollNo = M.RollNo;

Keeps only pairs where the common column is equal. RollNo appears twice (S.RollNo and M.RollNo). Use table aliases (S, M) and write table.column when a column name is in both tables. JOIN … ON gives the same result: SELECT * FROM student JOIN marks ON student.RollNo = marks.RollNo;

Natural join

SELECT * FROM student NATURAL JOIN marks;

Joins on all columns with the same name and shows the common column only once.

Try it: your class in SQL

Install MySQL or use any online SQL playground (for example one that runs SQLite in the browser). Create STUDENT with 8 friends, their city and marks. Answer with one query each: toppers above 80; names starting with 'S'; average marks per city; cities with more than 2 students; all students sorted by marks high to low. Before running each, predict the answer. Then compare with the 3D free-play step.

Key formulas and definitions

Worked examples

1. Create table ITEM: ICode (4 characters, primary key), IName (up to 25 characters, not null), Price (decimal), Qty (integer, default 0).

CREATE TABLE item (ICode CHAR(4) PRIMARY KEY, IName VARCHAR(25) NOT NULL, Price DECIMAL(8,2), Qty INT DEFAULT 0);

2. Add a column Category VARCHAR(15) to ITEM, then increase every price by 10%.

ALTER TABLE item ADD Category VARCHAR(15); UPDATE item SET Price = Price * 1.10;

3. STUDENT: (1 Asha Delhi 92), (2 Ravi Pune 75), (3 Mohan NULL 58), (4 Zoya Delhi 81), (5 Kabir Jaipur 66). Output of SELECT Name FROM student WHERE Marks BETWEEN 60 AND 80 ORDER BY Marks DESC;

Rows with Marks 60–80: Ravi 75, Kabir 66. Sorted high to low: Ravi, Kabir.

4. Same table. Output of SELECT COUNT(*), COUNT(City), COUNT(DISTINCT City) FROM student;

COUNT(*) = 5 rows. COUNT(City) = 4 (Mohan's NULL is skipped). COUNT(DISTINCT City) = 3 (Delhi, Pune, Jaipur).

5. Same table. Write queries for names starting with 'A' or 'Z', and for names with 'a' as the second letter.

SELECT Name FROM student WHERE Name LIKE 'A%' OR Name LIKE 'Z%'; → Asha, Zoya SELECT Name FROM student WHERE Name LIKE '_a%'; → Ravi, Kabir

6. Same table. Output of SELECT City, AVG(Marks) FROM student WHERE City IS NOT NULL GROUP BY City HAVING COUNT(*) > 1;

WHERE removes Mohan. Groups: Delhi (92, 81), Pune (75), Jaipur (66). HAVING COUNT(*) > 1 keeps Delhi only. Output: Delhi 86.5.

7. STUDENT has 5 rows and 5 columns; MARKS(RollNo, Subject, Score) has 4 rows. How many rows and columns does SELECT * FROM student, marks; return?

Cartesian product: rows 5 × 4 = 20; columns 5 + 3 = 8.

8. Write an equi-join to show each student's Name with Subject and Score, and the natural join version.

SELECT S.Name, M.Subject, M.Score FROM student S, marks M WHERE S.RollNo = M.RollNo; SELECT Name, Subject, Score FROM student NATURAL JOIN marks;

Common mistakes

Practice quiz

1. Which is a DDL command?
2. Which clause filters groups?
3. LIKE '_a%' matches names whose:
4. Which function counts rows including NULLs?
5. Table A has 4 rows, B has 3 rows. The Cartesian product has:

Practice: answer these yourself

Type or choose your answer, then press Check. Use a hint if you are stuck; the full solution appears after you answer.

Frequently asked questions

What is the difference between GROUP BY and HAVING?

GROUP BY makes groups of rows with the same value. HAVING filters those groups using a condition, often on an aggregate.

What are aggregate functions in SQL?

Functions that summarise many rows into one value: COUNT, SUM, AVG, MAX and MIN.

What is the difference between equi-join and natural join?

An equi-join matches rows with an = condition on a common column and shows that column twice. A natural join matches on same-named columns automatically and shows the common column once.

Where this is taught

Ukraine11 класDatabases
CBSE (India)Class 12Database Management
CBSE (India)Class 12Database Query using SQL
CBSE (India)Class 12Database Concepts: RDBMS Tool
England (GCSE, A level)Year 134.10 Fundamentals of databases

Learn first

Learn next

Related lessons

All Computer Science lessons