G27
Self-checkedTier 1 9 min readdbms.sql-basics

SQL: DDL and basic queries

SQL as a language: defining tables (data types, NOT NULL, PRIMARY KEY, UNIQUE, FOREIGN KEY, DEFAULT), changing data (INSERT, UPDATE, DELETE), the SELECT-FROM-WHERE query and its meaning in relational algebra, DISTINCT and the bag semantics of SQL, expressions and aliases, ORDER BY and LIMIT, pattern and range conditions (LIKE, BETWEEN, IN, IS NULL), NULL in conditions, and the set operations UNION, INTERSECT and EXCEPT with their ALL forms; every statement shown was executed on a real SQL engine.

Why it exists

SQL is the language in which relational databases are used. Its core is a direct, declarative translation of relational algebra and calculus. GATE asks the result of SQL queries on a given instance, the effect of INSERT/UPDATE/DELETE, equivalence of queries, and the meaning of NULL. The statements shown here were executed on a real engine (SQLite); the printed results are its output, not typed by hand.

Prerequisites

You need relational algebra (relational algebra), which gives the meaning of SELECT, FROM and WHERE.

Precise definitions

Sample database (used on all SQL pages): students, courses, enrolments, instructors.

The sample database: start

Computed, not typed
Student8 tuples
sidsnamedeptage
1AshaCS20
2BilalEE22
3ChenCS21
4DaraMENULL
5EshaCS23
6FaridEE21
7GitaME22
8HariCS20
Course6 tuples
cidtitlecreditsdept
C1DB4CS
C2OS3CS
C3CN3CS
C4AI3CS
C5Circuits4EE
C6Thermo3ME
Enrolled14 tuples
sidcidgrade
1C1A
1C2B
2C1B
2C5A
3C1NULL
3C2A
3C3A
5C1A
5C2C
6C5B
7C6A
8C1B
8C3A
8C4B
Instructor4 tuples
iidinamedeptsalary
10RaoCS90000
11IyerCS80000
12KhanEE70000
13LalMENULL
Teaches6 tuples
iidcid
10C1
10C2
11C3
11C4
12C5
13C6

Step 0

The sample database used on the SQL pages: 8 students, 6 courses, 14 enrolments, 4 instructors. Note the NULL values: Dara has no age, Chen's grade in C1 is not recorded, Lal has no salary.

0 / 0
computed by script: the SQL statements are executed by SQLite, the calculus formulas are evaluated over a finite domain (scripts/db_sql.py, scripts/db_lib.py). python3 scripts/gen-db2-traces.py

Data definition (DDL). CREATE TABLE name (column type [constraints], ..., table constraints) defines a schema; ALTER TABLE changes it; DROP TABLE removes it. Typical column types: INTEGER, DECIMAL(p, s), CHAR(n), VARCHAR(n), DATE, BOOLEAN. Column or table constraints: NOT NULL, PRIMARY KEY, UNIQUE, DEFAULT value, CHECK (condition), FOREIGN KEY (...) REFERENCES T(...).

Data manipulation (DML). INSERT INTO T [(columns)] VALUES (...) or INSERT INTO T SELECT ...; UPDATE T SET column = expression [WHERE condition]; DELETE FROM T [WHERE condition] (without WHERE it deletes all rows).

Query. SELECT [DISTINCT] expressions FROM tables [WHERE condition] [ORDER BY ...] [LIMIT n]. Meaning in algebra: the FROM clause gives the Cartesian product (or joins) of the tables, WHERE is a selection σ\sigma, the SELECT list is a projection π\pi (with renaming and computed columns), DISTINCT removes duplicates, ORDER BY sorts the output. Unlike the algebra, SQL works on bags: duplicates are kept unless DISTINCT (or a set operation) removes them.

How it works

Defining and changing tables

CREATE TABLE Club (cid INTEGER PRIMARY KEY, cname TEXT NOT NULL UNIQUE, founded INTEGER CHECK (founded >= 1900), dept TEXT DEFAULT 'CS');
INSERT INTO Club (cid, cname, founded) VALUES (1, 'Robotics', 2010);
INSERT INTO Club VALUES (2, 'Chess', 1995, 'EE');
SELECT * FROM Club;
cid | cname    | founded | dept
----+----------+---------+-----
1   | Robotics | 2010    | CS
2   | Chess    | 1995    | EE
(2 rows)

The column dept of the first club was not given, so the DEFAULT was used. A statement that violates a constraint is refused as a whole:

-- error
CREATE TABLE Club (cid INTEGER PRIMARY KEY, cname TEXT NOT NULL UNIQUE, founded INTEGER CHECK (founded >= 1900), dept TEXT DEFAULT 'CS');
INSERT INTO Club (cid, cname, founded) VALUES (1, 'Robotics', 1850);
Error: CHECK constraint failed: founded >= 1900

UPDATE and DELETE act on all rows that satisfy the WHERE condition:

UPDATE Student SET age = age + 1 WHERE dept = 'ME';
OK (2 rows affected)

The ME students are Dara (age NULL) and Gita (22). NULL + 1 is NULL, so Dara's age stays NULL; only Gita changes, and the engine counts both rows as affected because both satisfy the condition. A DELETE with no WHERE removes every row:

DELETE FROM Enrolled WHERE grade IS NULL;
SELECT COUNT(*) AS remaining FROM Enrolled;
remaining
---------
13
(1 row)

SELECT, DISTINCT and bags

SELECT dept FROM Student;
dept
----
CS
EE
CS
ME
CS
EE
ME
CS
(8 rows)

Eight rows: SQL keeps duplicates. In relational algebra πdept(Student)\pi_{\text{dept}}(\text{Student}) would have three tuples. DISTINCT turns the result into a set:

SELECT DISTINCT dept FROM Student;
dept
----
CS
EE
ME
(3 rows)

Expressions, aliases, sorting

SELECT sname AS name, age + 1 AS next_year, credits * 2 AS double_credits FROM Student, Course WHERE Student.sid = 1 AND Course.cid = 'C1';
name | next_year | double_credits
-----+-----------+---------------
Asha | 21        | 8
(1 row)

Columns may be computed and renamed with AS. Sorting and limiting:

SELECT sname, age FROM Student ORDER BY age DESC, sname LIMIT 3;
sname | age
------+----
Esha  | 23
Bilal | 22
Gita  | 22
(3 rows)

ORDER BY puts NULLs first or last depending on the system (here the NULL of Dara sorts as the smallest value, so it is last in descending order). Without ORDER BY the order of rows is not defined.

Conditions: ranges, lists, patterns, NULL

SELECT sname FROM Student WHERE age BETWEEN 21 AND 22 AND dept IN ('CS', 'EE');
sname
-----
Bilal
Chen
Farid
(3 rows)

BETWEEN a AND b includes both ends. A pattern uses % (any string, also empty) and _ (exactly one character):

SELECT sname FROM Student WHERE sname LIKE '_a%';
sname
-----
Dara
Farid
Hari
(3 rows)

The names whose second letter is a are Dara, Farid and Hari. NULL needs its own test: a comparison with NULL is UNKNOWN, so = NULL never selects anything:

SELECT sname FROM Student WHERE age = NULL;
sname
-----
(0 rows)
SELECT sname FROM Student WHERE age IS NULL;
sname
-----
Dara
(1 row)

A row is returned only if the condition is TRUE; age <> 21 also drops Dara, because NULL <> 21 is UNKNOWN. (The full truth tables are on the page on nested queries.)

Set operations

UNION, INTERSECT and EXCEPT combine the results of two queries with the same number of compatible columns and remove duplicates. UNION ALL keeps them (the SQL standard also has INTERSECT ALL and EXCEPT ALL; SQLite implements only UNION ALL).

SELECT dept FROM Student UNION SELECT dept FROM Course;
dept
----
CS
EE
ME
(3 rows)
SELECT dept FROM Student UNION ALL SELECT dept FROM Course;
dept
----
CS
EE
CS
ME
CS
EE
ME
CS
CS
CS
CS
CS
EE
ME
(14 rows)

The UNION has 3 rows, the UNION ALL has 8+6=148 + 6 = 14.

SELECT sid FROM Student EXCEPT SELECT sid FROM Enrolled;
sid
---
4
(1 row)

EXCEPT is the algebra difference: the students with no enrolment.

Worked examples

EX 1From algebra to SQL

Easy

πsname(σdept=’CS’(Student))\pi_{\text{sname}}(\sigma_{\text{dept}=\text{'CS'}}(\text{Student})) is SELECT DISTINCT sname FROM Student WHERE dept = 'CS'. Without DISTINCT the answer is a bag; here names happen to be distinct, so the two agree.

EX 2Count rows of a result

Easy

SELECT dept FROM Student returns 88 rows (one per student). SELECT DISTINCT dept FROM Student returns 33. SELECT * FROM Student, Course returns 8⋅6=488 \cdot 6 = 48 rows (Cartesian product).

EX 3NULL in a condition

Medium

SELECT sname FROM Student WHERE age <> 21 returns the students whose age is known and different from 21: Asha (20), Bilal (22), Esha (23), Gita (22), Hari (20). Dara (NULL) and Chen and Farid (age 21) are not returned. To include Dara: ... OR age IS NULL.

EX 4UPDATE with a computed value

Medium

UPDATE Student SET age = age + 1 WHERE dept = 'ME' changes Gita from 22 to 23 and leaves Dara at NULL (arithmetic with NULL gives NULL). The statement affects two rows in the sense that both satisfy the WHERE condition.

EX 5Typical questions

GATE level

(a) "What is the output of SELECT COUNT(*) FROM R, S when RR has 5 and SS has 6 rows?" 3030. (b) "Which clause eliminates duplicates?" DISTINCT (and UNION, INTERSECT, EXCEPT). (c) "DELETE FROM T removes:" all rows, the table remains. (d) "DROP TABLE T removes:" the table and its data. (e) "WHERE x = NULL returns:" no rows. (f) "In LIKE 'a_%', which strings match?" Strings of at least two characters starting with a.

Cheat box

Cheat box

  • SELECT = π\pi, FROM = ×\times / ⋈\bowtie, WHERE = σ\sigma; SQL works on bags: DISTINCT, UNION, INTERSECT, EXCEPT remove duplicates, UNION ALL keeps them.
  • x = NULL is never true: use IS NULL / IS NOT NULL.
  • LIKE: % = any string, _ = one character. BETWEEN a AND b includes both ends.
  • DELETE FROM T (no WHERE) empties the table; DROP TABLE removes it; TRUNCATE is a faster delete-all in many systems.
  • Without ORDER BY the row order is undefined.

Traps and GATE patterns

Connections

Joins and aggregation come next (joins and aggregates); constraints and triggers extend the DDL (constraints and triggers); the calculus gives the logical meaning (tuple relational calculus).

PYQs

6 previous year questions from your book. I re-solved each one myself (5 by running or simulating, 1 by reasoning only); the book's key is shown next to my answer. All PYQs

GATE 2021 · Set 1 · NAT · 1 markQ6 · page 389 of the book
A relation r(A, B) in a relational database  has 1200
tuples. The attribute A has integer values ranging from 6
to 20, and the attribute B has integer values ranging from
1 to 20. Assume that the attribute A and B  are
independently distributed.  The estimated number of
tuples in the output of σ(A>10)v(B=18)(r) is ______.
GATE 2025 · Set 2 · MSQ · 2 marksQ1 · page 400 of the book
Consider the following relational schema:

Students(rollno: integer, name: string, age: integer,
cgpa: real)
Courses(courseno: integer,cname: string, credits:
integer)
Enrolled( rollno: integer,courseno: integer,grade:
string)

Which of the following options is/are correct SQL
query/queries to retrieve the names of the students
enrolled in course number (i.e. courseno) 1470?
  • (a)SELECT S.name FROM Students S WHERE EXISTS (SELECT * FROM Enrolled E WHERE E.courseno = 1470 AND E.rollno = S.rollno)
  • (b)SELECT S.name FROM Students S WHERE SIZEOF (SELECT * FROM Enrolled E WHERE E.courseno = 1470 AND E.rollno = S.rollno) > 0
  • (c)SELECT S.name FROM Students S WHERE 0 < (SELECT COUNT(*) FROM Enrolled E WHERE E.courseno = 1470 AND E.rollno = S.rollno)
  • (d)SELECT S.name FROM Students S NATURAL JOIN Enrolled E WHERE E.courseno = 1470
GATE 2023 · NAT · 2 marksQ4 · page 401 of the book
Consider the following table named Student in a
relational database. The primary key of this table is
rollNum.

rollINum
name
gender
marks
1
Naman
M
62
2
Aliya
F
70
3
Aliya
F
80
4
James
M
82
5
Swati
F
65

The SQL query below is executed on this database.

SELECT *FROM Student
WHERE gender = 'F' AND  marks  > 65;
The number of rows returned by the query is
___________.
GATE 2015 · Set 1 · MCQ · 1 markQ14 · page 404 of the book
SELECT operation in SQL is equivalent to
  • (a)the selection operation in relational algebra
  • (b)that operations in relations algebra, except that SELECT IN SQL retains duplicates
  • (c)the projection operation in relational algebra
  • (d)the projection operation in relational algebra except that SELECT in SQL retains duplicates
GATE 2014 · Set 2 · MCQQ17 · page 405 of the book
SQL allows duplicates tuples in relations, and
correspondingly defines the multiplicity of tuples in the
result of joins. Which one of the following queries
always gives the same answer as the nested query
shown below:

select * from R

where a in (select S.a from S)
  • (a)select R.* from R,S where R.a=S.a
  • (b)select distinct R.* from R,S where R.a=S.a
  • (c)select R.* from R,(select distinct a from S) as S1 where R.a = S1.a
  • (d)select R * from R,S where R.a=S.a and is unique R
GATE 2011 · MCQ · 2 marksQ22 · page 406 of the book
Consider a database table T containing two columns X
and Y each of type integer. After the creation of the table,
one record (X=1, Y=1) is inserted in the table. Let MX
and MY denote the respective maximum values of X and
Y among all records in the table at any point in time.
Using MX and MY, new records are inserted in the table
128 times with X and Y values being MX+1, 2*MY+1
respectively. It may be noted that each time after the
insertion, values of MX and MY change.

What will be the output of the following SQL query after
the steps mentioned above are carried out?

SELECT Y

FROM T

WHERE X=7;
  • (a)127
  • (b)255
  • (c)129
  • (d)257

Self-check

Question 1

How many rows does SELECT * FROM Student, Course return on the sample database?

Show answer

8⋅6=488 \cdot 6 = 48.

Question 2

Why does SELECT sname FROM Student WHERE age = NULL return nothing?

Show answer

The comparison is UNKNOWN for every row, and WHERE keeps only rows for which the condition is TRUE. Use IS NULL.

Question 3

What is the difference between UNION and UNION ALL?

Show answer

UNION removes duplicate rows from the result, UNION ALL keeps them.

Question 4

Which statement removes all rows but keeps the table definition?

Show answer

DELETE FROM T without a WHERE clause (or TRUNCATE in systems that have it).

Revision card

One-screen revision

  • DDL: CREATE/ALTER/DROP TABLE with constraints. DML: INSERT, UPDATE, DELETE.
  • SELECT-FROM-WHERE = πσ×\pi\sigma\times on bags; DISTINCT for sets.
  • NULL: IS NULL; comparisons with NULL are UNKNOWN.
  • UNION / INTERSECT / EXCEPT remove duplicates; UNION ALL keeps them.

References

  • ·Silberschatz, Korth, Sudarshan, Database System Concepts (7th edition), Chapter 3 (introduction to SQL) and Chapter 4 (intermediate SQL, Sections 4.1 to 4.4)
  • ·Elmasri, Navathe, Fundamentals of Database Systems (7th edition), Chapter 6 (basic SQL)

Verification

scripts/db_sql.py executes every verified SQL block of this page (marked sql verify) on a fresh in-memory SQLite database holding the sample university database and writes the output shown under it; scripts/enum-checks/db_sqlcheck.py re-runs all of them and fails if any printed output differs. Features that SQLite does not implement or implements differently (ANY/ALL, CHECK semantics are the same, case-sensitivity of LIKE for non-ASCII letters, strict typing of column types, FULL and RIGHT join are supported) are described as 'in the SQL standard' only and are not run; this page makes no claim that is specific to another system except where marked. The mapping from SELECT-FROM-WHERE to algebra was checked on random relations (the algebra operators equal the SQL queries; see the relational algebra pages). The bag semantics (UNION ALL, INTERSECT ALL counts) follow the SQL standard; SQLite does not implement INTERSECT ALL or EXCEPT ALL, so only the set forms and UNION ALL are run. Textbook chapter references are from memory. SECOND PASS (2026-11-02, done by the assistant, not a human check): every Self-check question was solved before the printed answer was read and all agreed; the definitions, worked examples, cheat box and traps were read claim by claim and re-derived against the textbook definitions and the sample database. No defect found. Status raised to self-checked; verified needs a textbook or human check.

last verified: never