Current Affairs updated daily
KalviGavaniKalviGavani
Class 12 · Tamil Nadu State Board

Samacheer Kalvi 12th Computer Science Chapter 15 Data Manipulation Through SQL Exercise Solutions | KalviGavani

Complete TN Board Class 12 Computer Science Chapter 15 Data Manipulation Through SQL exercise solutions — aggregate functions, GROUP BY, HAVING, subqueries, JOINs, set operations, views with worked SQL and Python sqlite3 examples.

Updated 13 June 202612 min read

Chapter 15 — Data Manipulation Through SQL: Exercise Solutions Guide

How to Use This Page

1. Attempt every exercise in your Samacheer Kalvi textbook on your own first. 2. Compare your answers with the solutions below — focus on the method, not just the final result. 3. Practise the SQL statements on a computer using SQLite or MySQL. 4. Review the Common Mistakes and Exam Checklist before your exam.


Key Concepts

Aggregate Functions

FunctionDescriptionExample
COUNT()Number of rowsSELECT COUNT(*) FROM student;
SUM()Total of valuesSELECT SUM(mark) FROM student;
AVG()Average of valuesSELECT AVG(mark) FROM student;
MAX()Largest valueSELECT MAX(mark) FROM student;
MIN()Smallest valueSELECT MIN(mark) FROM student;

GROUP BY and HAVING

-- GROUP BY: Group rows sharing a column value
SELECT dept, COUNT(*) FROM student GROUP BY dept;

-- HAVING: Filter groups (must follow GROUP BY)
SELECT dept, AVG(mark) FROM student
GROUP BY dept
HAVING AVG(mark) > 75;

Subqueries (Nested Queries)

A query placed inside another query:

-- Subquery in WHERE
SELECT * FROM student
WHERE mark > (SELECT AVG(mark) FROM student);

JOINs

TypeDescription
INNER JOINRows matching in both tables
LEFT JOINAll rows from left table + matched from right
RIGHT JOINAll rows from right table + matched from left

Set Operations

OperationDescription
UNIONCombines results, removes duplicates
INTERSECTRows common to both queries
EXCEPT / MINUSRows in first but not in second

Views

A view is a virtual table based on a query:

CREATE VIEW honors AS
SELECT name, mark FROM student WHERE mark > 90;

Multiple Choice Questions

Q1. Which aggregate function returns the total of numeric values?

  • (a) COUNT   (b) AVG   (c) SUM   (d) MAX
Answer(c) SUM — SUM(column) adds all values in the column.

Q2. The HAVING clause is used to filter:

  • (a) Individual rows   (b) Groups formed by GROUP BY   (c) Columns   (d) Tables
Answer(b) Groups formed by GROUP BY — HAVING works on aggregated results.

Q3. Which JOIN returns only matching rows from both tables?

  • (a) LEFT JOIN   (b) RIGHT JOIN   (c) INNER JOIN   (d) FULL JOIN
Answer(c) INNER JOIN — returns rows where the join condition matches in both tables.

Q4. A subquery is:

  • (a) A query inside another query   (b) A join operation   (c) A table   (d) A view
Answer(a) A query inside another query — also called a nested query or inner query.

Q5. UNION removes duplicate rows. Which keyword includes duplicates?

  • (a) UNION ALL   (b) UNION DISTINCT   (c) MERGE   (d) COMBINE
Answer(a) UNION ALL — includes all rows including duplicates; UNION removes them.

Q6. A VIEW is:

  • (a) A physical table stored on disk   (b) A virtual table based on a query   (c) An index   (d) A constraint
Answer(b) A virtual table based on a query — a view does not store data itself; it displays data from underlying tables.

Fill in the Blanks

1. The ______ function returns the number of rows in a result. → COUNT() 2. The clause used to group rows that share a value is ______. → GROUP BY 3. ______ keyword removes duplicate rows from the UNION result. → UNION (UNION removes duplicates by default; UNION ALL keeps them) 4. A query nested inside another query is called a ______. → subquery (or nested query) 5. The ______ clause filters groups after aggregation. → HAVING 6. A ______ is a virtual table that displays data from one or more tables. → view


True or False

1. Aggregate functions can be used in the WHERE clause.
AnswerFalse — use HAVING for aggregate conditions after GROUP BY. 2. GROUP BY must always be used with at least one aggregate function. → True — grouping without aggregation is usually meaningless. 3. A view stores data physically on disk. → False — a view is a stored query; data comes from underlying tables at runtime. 4. INTERSECT returns rows that appear in both queries. → True 5. A subquery can be used in the FROM clause. → True — called a derived table or inline view. 6. COUNT() and COUNT(column) always return the same value. → False — COUNT() counts all rows including NULLs; COUNT(column) excludes NULLs in that column.

Match the Following

Column AColumn B
1. SUM()a. Smallest value
2. AVG()b. Number of rows
3. COUNT()c. Total of values
4. MIN()d. Average of values
5. MAX()e. Largest value
Answer1-c, 2-d, 3-b, 4-a, 5-e

Short Answer Questions

Q1. Explain the five aggregate functions with examples.

Using a student table with columns: name, mark, dept.

-- COUNT: Number of students
SELECT COUNT(*) FROM student;

-- SUM: Total marks
SELECT SUM(mark) FROM student;

-- AVG: Average mark
SELECT AVG(mark) FROM student;

-- MAX: Highest mark
SELECT MAX(mark) FROM student;

-- MIN: Lowest mark
SELECT MIN(mark) FROM student;

Q2. Differentiate between WHERE and HAVING.

FeatureWHEREHAVING
FiltersIndividual rowsGroups
Used withSELECT, UPDATE, DELETESELECT with GROUP BY
Aggregate functionsCannot useCan use
EvaluatedBefore GROUP BYAfter GROUP BY
-- WHERE: filter rows before grouping
SELECT dept, AVG(mark) FROM student WHERE mark > 40 GROUP BY dept;

-- HAVING: filter groups after aggregation
SELECT dept, AVG(mark) FROM student GROUP BY dept HAVING AVG(mark) > 75;

Q3. What is a subquery? Give an example.

A subquery (nested query) is a SELECT statement embedded inside another query.

-- Find students scoring above average
SELECT name, mark FROM student
WHERE mark > (SELECT AVG(mark) FROM student);

-- Subquery in FROM (derived table)
SELECT dept, avg_mark
FROM (SELECT dept, AVG(mark) AS avg_mark FROM student GROUP BY dept) AS dept_avg
WHERE avg_mark > 70;

Q4. Explain INNER JOIN with an example.

INNER JOIN returns only the rows where there is a match in both tables.

-- Tables: student(roll, name, dept_id), department(dept_id, dept_name)

SELECT s.name, d.dept_name
FROM student s
INNER JOIN department d ON s.dept_id = d.dept_id;

Only students with a matching dept_id in the department table are returned.

Q5. What is a view? Write the syntax to create and drop a view.

A view is a virtual table defined by a stored SELECT query. It simplifies complex queries and restricts data access.

-- Create a view
CREATE VIEW high_scorers AS
SELECT name, mark FROM student WHERE mark >= 90;

-- Query the view like a table
SELECT * FROM high_scorers;

-- Drop the view
DROP VIEW high_scorers;

Detailed Answer Questions

Q1. Explain GROUP BY with HAVING using a detailed example.

Consider a sales table: salesperson, region, amount.

-- Create and populate the table
CREATE TABLE sales (
    id INT PRIMARY KEY,
    salesperson VARCHAR(30),
    region VARCHAR(20),
    amount INT
);

INSERT INTO sales VALUES
(1, 'Arun', 'North', 5000),
(2, 'Bala', 'South', 7000),
(3, 'Arun', 'North', 3000),
(4, 'Chitra', 'South', 9000),
(5, 'Bala', 'North', 6000),
(6, 'Chitra', 'South', 8000);

GROUP BY — aggregate per group:

-- Total sales by region
SELECT region, SUM(amount) FROM sales GROUP BY region;

-- Result:
-- North | 14000
-- South | 24000

HAVING — filter groups:

-- Regions with total sales above 15000
SELECT region, SUM(amount) AS total
FROM sales
GROUP BY region
HAVING SUM(amount) > 15000;

-- Result:
-- South | 24000

Order of execution: FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY

Q2. Write Python code to create an SQLite database, create a table, insert data, and query using aggregate functions.

import sqlite3

# Step 1: Connect to database (creates file if not exists)
conn = sqlite3.connect("school.db")
cur = conn.cursor()

# Step 2: Create table
cur.execute('''
    CREATE TABLE IF NOT EXISTS student (
        roll_no INT PRIMARY KEY,
        name TEXT NOT NULL,
        dept TEXT,
        mark INT
    )
''')

# Step 3: Insert data
students = [
    (1, "Arun", "CS", 92),
    (2, "Bala", "CS", 85),
    (3, "Chitra", "IT", 78),
    (4, "Deepa", "IT", 91),
    (5, "Ezhil", "CS", 67)
]
cur.executemany("INSERT INTO student VALUES (?, ?, ?, ?)", students)
conn.commit()

# Step 4: Aggregate functions
print("Total students:", cur.execute("SELECT COUNT(*) FROM student").fetchone()[0])
print("Average mark:", cur.execute("SELECT AVG(mark) FROM student").fetchone()[0])
print("Highest mark:", cur.execute("SELECT MAX(mark) FROM student").fetchone()[0])
print("Lowest mark:", cur.execute("SELECT MIN(mark) FROM student").fetchone()[0])
print("Total marks:", cur.execute("SELECT SUM(mark) FROM student").fetchone()[0])

# Step 5: GROUP BY
print("\nAverage mark by department:")
for row in cur.execute("SELECT dept, AVG(mark) FROM student GROUP BY dept"):
    print(f"  {row[0]}: {row[1]:.2f}")

# Step 6: HAVING
print("\nDepartments with average above 80:")
for row in cur.execute("SELECT dept, AVG(mark) FROM student GROUP BY dept HAVING AVG(mark) > 80"):
    print(f"  {row[0]}: {row[1]:.2f}")

conn.close()

Q3. Explain subqueries with multiple examples.

Example 1: Subquery in WHERE clause — find students above average

SELECT name, mark FROM student
WHERE mark > (SELECT AVG(mark) FROM student);

Example 2: Subquery with IN — find students in specific departments

SELECT name FROM student
WHERE dept IN (
    SELECT dept_name FROM department WHERE location = 'Chennai'
);

Example 3: Subquery in FROM clause (derived table)

SELECT dept, avg_mark
FROM (
    SELECT dept, AVG(mark) AS avg_mark
    FROM student
    GROUP BY dept
) AS dept_avg
WHERE avg_mark > 80;

Example 4: Correlated subquery — find the highest scorer in each department

SELECT name, dept, mark
FROM student s
WHERE mark = (
    SELECT MAX(mark)
    FROM student
    WHERE dept = s.dept
);

Example 5: Subquery in SELECT clause

SELECT name, mark,
    (SELECT AVG(mark) FROM student) AS overall_avg
FROM student;

Q4. Explain all types of JOINs with examples.

Using two tables:

  • student(roll, name, dept_id)
  • department(dept_id, dept_name)

INNER JOIN — only matching rows:

SELECT s.name, d.dept_name
FROM student s
INNER JOIN department d ON s.dept_id = d.dept_id;
ResultOnly students whose dept_id exists in the department table.

LEFT JOIN — all rows from left table, matched from right:

SELECT s.name, d.dept_name
FROM student s
LEFT JOIN department d ON s.dept_id = d.dept_id;
ResultAll students; if no matching department, dept_name is NULL.

RIGHT JOIN — all rows from right table, matched from left:

SELECT s.name, d.dept_name
FROM student s
RIGHT JOIN department d ON s.dept_id = d.dept_id;
ResultAll departments; if no matching student, name is NULL.

Comparison Table:

Join TypeReturns
INNEROnly matching rows from both tables
LEFTAll left rows + matched right rows (NULL if no match)
RIGHTAll right rows + matched left rows (NULL if no match)

Q5. Explain set operations (UNION, INTERSECT, EXCEPT) with examples.

Using two tables:

  • cricket_players(name)
  • football_players(name)

UNION — all unique rows from both queries:

SELECT name FROM cricket_players
UNION
SELECT name FROM football_players;
ResultStudents who play cricket OR football (duplicates removed).

UNION ALL — all rows including duplicates:

SELECT name FROM cricket_players
UNION ALL
SELECT name FROM football_players;

INTERSECT — rows common to both queries:

SELECT name FROM cricket_players
INTERSECT
SELECT name FROM football_players;
ResultStudents who play BOTH cricket AND football.

EXCEPT (MINUS in Oracle) — rows in first but not in second:

SELECT name FROM cricket_players
EXCEPT
SELECT name FROM football_players;
ResultStudents who play cricket but NOT football.

Rules for set operations: 1. Both queries must return the same number of columns. 2. Corresponding columns must have compatible data types. 3. Column names come from the first query.


Common Mistakes

MistakeWhy It's WrongFix
Using aggregate functions in WHEREWHERE runs before groupingUse HAVING with GROUP BY
WHERE mark > AVG(mark)AVG is an aggregate; cannot appear in WHEREUse a subquery: WHERE mark > (SELECT AVG(mark) FROM student)
GROUP BY without aggregateGrouping is meaningless without aggregationAlways pair GROUP BY with COUNT, SUM, AVG, etc.
Confusing UNION and JOINUNION stacks rows vertically; JOIN combines columns horizontallyUse UNION to merge similar result sets; JOIN to relate tables
Forgetting conn.commit() in sqlite3Data changes (INSERT, UPDATE, DELETE) are not savedCall conn.commit() after DML operations
Not using table aliases in JOINsLong table names make queries hard to readUse FROM student s INNER JOIN department d ON ...
Creating a view with duplicate column namesView creation failsUse column aliases: SELECT s.name AS student_name, ...

Exam Checklist

  • [ ] Can write all five aggregate functions (COUNT, SUM, AVG, MAX, MIN) with examples
  • [ ] Can differentiate WHERE and HAVING with examples
  • [ ] Can write GROUP BY queries with and without HAVING
  • [ ] Can write subqueries in WHERE, FROM, and SELECT clauses
  • [ ] Can write INNER JOIN, LEFT JOIN, and RIGHT JOIN queries
  • [ ] Understand UNION, INTERSECT, and EXCEPT set operations
  • [ ] Can create and query views using CREATE VIEW
  • [ ] Can use sqlite3 module: connect, cursor, execute, commit, close
  • [ ] Can write Python programs that interact with SQLite databases
  • [ ] Know the order of SQL execution: FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY

Frequently Asked Questions

The built-in sqlite3 module. Connect with sqlite3.connect('file.db'), create a cursor with conn.cursor(), execute SQL with cursor.execute(), and save changes with conn.commit().
← Browse all Class 12 Exercise Solutions

More exercise solutions