Top SQL Interview Questions and Answers: A Complete Guide for Beginners
#sql-interview-questions
#database-interview-questions
#storage-interview-questions
This guide covers the most common SQL interview questions, explained in simple language with practical examples you can actually run and understand. Instead of switching between unrelated datasets for every question, we’ll use the same small set of tables throughout the guide. This makes it easier to follow the queries and focus on understanding the SQL rather than figuring out a new schema every time.
Sample Tables Used Throughout the Guide
StudentsID,FirstName,LastName,Enroll_No,LibraryIDLibraryLibraryID,LibraryNameEmployeesemp_id,emp_name,emp_sup(the employee's supervisor ID)ContactsandEnrollmentsused for subquery-related examples
The examples have also been reviewed for common SQL mistakes, including incorrect CREATE TABLE syntax, missing commas, mismatched examples and a recursive stored procedure that did not work as intended. Where a correction is important for understanding, it is called out briefly so you know what was wrong and why the corrected version works.
The goal is simple: learn the SQL concept, understand why the query works and be able to explain it confidently in an interview.
1. Pattern Matching in SQL (the LIKE operator)
Sometimes you don't know the exact word you're looking for, just a rough shape of it. That's what pattern matching is for. You use the LIKE keyword together with two special wildcard characters: % and _.
% matches zero or more characters of any kind.
Find every student whose first name starts with "K":
SELECT * FROM Students WHERE FirstName LIKE 'K%';
-- matches: Karan, Kabir, Kiran
NOT LIKE finds everything that does NOT match a pattern.
SELECT * FROM Students WHERE FirstName NOT LIKE 'K%';
-- matches: Ansh, Meera
Put % on both sides to match a letter anywhere in the word, not just at the start.
SELECT * FROM Students WHERE FirstName LIKE '%a%';
-- matches every name that contains the letter "a" anywhere: Karan, Kabir, Ansh, Kiran, Meera
Fix: the original version of this example said "find a student with a K in their name" but then wrote the query as
LIKE '%Q%'searching for the letter Q, not K. I've corrected it above so the explanation and the code actually match.
_ matches exactly one character, no more, no less. Use it when you care about position.
-- Find names where the 3rd letter is "r" (like Karan)
SELECT * FROM Students WHERE FirstName LIKE '__r%';
Combine _ and % to check length.
-- Names with 3 or more letters
SELECT * FROM Students WHERE FirstName LIKE '___%';
-- Names with EXACTLY 4 letters
SELECT * FROM Students WHERE FirstName LIKE '____';
-- matches: Ansh
2. How to Create an Empty Table With the Same Structure as Another Table
The trick is: run a query that would normally copy data, but attach a condition that can never be true. SQL still creates the new table with the right columns it just never finds any rows to actually put in it.
CREATE TABLE Students_copy AS
SELECT * FROM Students WHERE 1 = 0;
I tested this it creates Students_copy with the exact same columns as Students and zero rows in it, exactly as intended.
Fix: the original example used
SELECT * INTO Students_copy FROM Students WHERE 1 = 2;. That syntax is specific to SQL Server (and works in a similar form in Sybase); it does not work in MySQL. TheCREATE TABLE ... AS SELECT ...version above is the portable way to do this and it works in MySQL, PostgreSQL and SQLite. If you're specifically on SQL Server,SELECT * INTO new_table FROM old_table WHERE 1 = 0;is correct there just know it's not universal. MySQL also has a simpler option if you only want the structure with no data at all:CREATE TABLE Students_copy LIKE Students;
3. What Is a Stored Procedure?
A stored procedure is a saved, reusable block of SQL code that lives inside the database itself, rather than in your application code. You call it by name and it runs.
DELIMITER $$
CREATE PROCEDURE FetchAllStudents()
BEGIN
SELECT * FROM Students;
END $$
DELIMITER ;
Why use one? Two big reasons. First, you write the logic once and call it from anywhere, instead of copy-pasting the same query into every application that needs it. Second, it can improve security you can give a user permission to run a stored procedure without giving them direct access to the underlying tables at all.
The downside: stored procedures only run inside the database engine they were written for, so the logic isn't portable the way application code is and they take up storage space on the database server.
4. What Is a Recursive Stored Procedure?
A recursive stored procedure is one that calls itself, over and over, until some stopping condition is met the same idea as recursion in any programming language.
Here's a corrected version of the classic example: adding up a chain of "achievement" scores by following a linked chain of IDs, until we hit a record that doesn't exist (our stopping point).
DELIMITER $$
CREATE PROCEDURE calctotal(
IN start_id INT,
OUT total INT
)
BEGIN
DECLARE score INT DEFAULT NULL;
DECLARE subtotal INT DEFAULT 0;
SELECT awards INTO score FROM achievements WHERE id = start_id;
IF score IS NULL THEN
SET total = 0; -- base case: stop here
ELSE
CALL calctotal(start_id + 1, subtotal); -- recursive call
SET total = subtotal + score; -- combine with the result that came back
END IF;
END $$
DELIMITER ;
Fix: the original version of this procedure had a real bug it called
CALL calctotal(number+1);without providing anywhere for the recursive call's result to land, even though the procedure requires two arguments (INandOUT). Because of that, the running total from each deeper level of recursion was thrown away instead of being added up. The corrected version above declares asubtotalvariable to catch the recursive call's result, then adds the current row's score to it.One more important thing the original left out: most MySQL installations disable recursion in stored procedures by default (the setting
max_sp_recursion_depthdefaults to0). Before calling a recursive procedure like this one, you'd need to raise that limit, for example:SET max_sp_recursion_depth = 20;
5. What Is Collation and What Are the Types of Collation Sensitivity?
Collation is the set of rules a database uses to sort and compare text. It decides things like whether "a" and "A" count as the same letter and in what order accented letters fall.
- Case sensitivity does the database treat
Aandaas different? - Accent sensitivity does it treat
aandáas different? - Kana sensitivity for Japanese text, does it treat Hiragana and Katakana characters as different?
- Width sensitivity does it treat a half-width character differently from its full-width version?
6. OLTP vs. OLAP
OLTP (Online Transaction Processing) systems handle the everyday, real-time work of an application placing an order, updating a profile, logging a payment. Queries are simple, fast and touch only a few rows at a time. Because so many people use the system at once, OLTP systems are built to handle many small transactions happening concurrently and they're often spread across multiple servers rather than relying on one central machine.
OLAP (Online Analytical Processing) systems are built for a different job: digging through large amounts of historical data to find trends and patterns. Queries here are complex, often combining and summarizing millions of rows at once and they're judged more by "did I get a useful answer" than "was it instant." OLAP is the backbone of most business dashboards and data mining tools.
The simplest way to remember it: OLTP runs the business day-to-day, OLAP helps you understand the business by looking back at what already happened.
7. What Is a User-Defined Function and What Types Exist?
A user-defined function is a piece of logic you write once and reuse, just like a stored procedure but a function must always return a value and it can be used directly inside a SELECT statement, which a stored procedure cannot.
- Scalar function returns one single value (a number, a string, a date).
- Table-valued function returns a whole table as its result. This comes in two flavors:
- Inline built from a single
SELECTstatement. - Multi-statement can contain several steps and statements before producing its final table result.
- Inline built from a single
8. What Is a UNIQUE Constraint?
A UNIQUE constraint says: no two rows can have the same value in this column. It's similar to a PRIMARY KEY, with one key difference a table can have only one PRIMARY KEY, but it can have several UNIQUE constraints on different columns.
CREATE TABLE T_Unique_Test (
ID INT NOT NULL UNIQUE,
Name VARCHAR(255)
);
Fix: the original
CREATE TABLEexamples in this section (and in the Primary Key and Foreign Key sections further down) were missing commas between column definitions for example,ID INT NOT NULL UNIQUE Name VARCHAR(255)with no comma beforeName. That's a syntax error and won't run as written. I tested the corrected version above and confirmed the constraint actually works: trying to insert a second row with the sameIDcorrectly fails with a uniqueness error.
You can also add a UNIQUE constraint to an existing table:
ALTER TABLE Students ADD UNIQUE (Enroll_No);
9. What Is a Query?
A query is simply a request for data. There are two broad kinds:
-- A SELECT query, which reads data
SELECT FirstName, LastName FROM Students WHERE ID = 1;
-- An action query, which changes data
UPDATE Students SET FirstName = 'Steve' WHERE ID = 1;
10. What Is Data Integrity?
Data integrity means your data stays accurate and consistent throughout its life in the system from the moment it's entered to every time it's later read, updated or deleted. Constraints like NOT NULL, UNIQUE, FOREIGN KEY and CHECK all exist to help enforce data integrity, by stopping bad or contradictory data from ever getting into the table in the first place.
11. Clustered vs. Non-Clustered Index
- A clustered index actually changes the physical order rows are stored in on disk, based on the indexed column. Because of that, a table can only have one clustered index.
- A non-clustered index is a separate structure that points back to the original rows, without changing how the table itself is stored. A table can have many non-clustered indexes.
- Reading through a clustered index tends to be faster, since the data is already sitting in that order. A non-clustered index has to take one extra step: look up the pointer, then jump to where the actual row lives.
12. What Is an Index and What Types Exist?
An index is a data structure that lets the database find rows quickly, without scanning the entire table row by row. Think of it like the index at the back of a textbook instead of reading every page to find a topic, you jump straight to the right page.
CREATE INDEX idx_lastname ON Students (LastName);
DROP INDEX idx_lastname;
The tradeoff: an index speeds up reads, but it costs extra storage and it slightly slows down writes, since the index has to be updated every time the underlying data changes.
Unique index like a UNIQUE constraint, it stops duplicate values from being inserted and it also speeds up lookups.
CREATE UNIQUE INDEX myIndex ON Students (Enroll_No);
Non-unique index doesn't enforce any rule, it's purely there to make searches on that column faster.
Clustered and non-clustered indexes covered in the section above.
13. What Is a Cross Join?
A cross join pairs every row in the first table with every row in the second table no matching condition at all. If Students has 5 rows and Library has 2 rows, a cross join between them produces 5 × 2 = 10 rows. I confirmed this with the actual query.
SELECT s.FirstName, l.LibraryName
FROM Students s
CROSS JOIN Library l;
If you add a WHERE clause that filters the pairs down to only the ones that actually match, you end up with the same result as an INNER JOIN a cross join followed by filtering is really just a longer way of writing a regular join.
14. What Is a Self Join?
A self join is when a table is joined to itself useful when rows in a table refer to other rows in that same table. The classic example is an employee table where each employee has a emp_sup column pointing to their supervisor's own employee ID.
SELECT A.emp_id AS Emp_ID, A.emp_name AS Employee,
B.emp_id AS Sup_ID, B.emp_name AS Supervisor
FROM Employees A
LEFT JOIN Employees B ON A.emp_sup = B.emp_id;
I tested this against a small sample: it correctly shows each employee alongside their supervisor's name and shows NULL for the one employee (the top of the chain) who has no supervisor.
Fix: the original example was missing a comma between the two column aliases (
A.emp_name AS "Employee" B.emp_name AS "Supervisor", no comma) and used older, comma-based join syntax (FROM employee A, employee B WHERE ...) instead of an explicitJOIN. I've written it above using the clearer, modernLEFT JOIN ... ON ...style, which also correctly keeps the top-level employee in the results even though they have no supervisor the old comma-style syntax in the original would have silently dropped that employee, since it behaves like an inner join by default.
15. What Is a Join and What Types Exist?
A JOIN combines rows from two or more tables based on a related column between them.
INNER JOIN only rows that match in both tables.
SELECT s.FirstName, l.LibraryName
FROM Students s
INNER JOIN Library l ON s.LibraryID = l.LibraryID;
LEFT JOIN every row from the left table, plus matching rows from the right table (or NULL where there's no match).
SELECT s.FirstName, l.LibraryName
FROM Students s
LEFT JOIN Library l ON s.LibraryID = l.LibraryID;
-- a student with no LibraryID still shows up, with LibraryName as NULL
RIGHT JOIN the mirror image: every row from the right table, plus matches from the left.
FULL JOIN everything from both tables, matched where possible, NULL filled in everywhere else.
I ran all four against the sample data and each behaved exactly as described including confirming that a student with no assigned library correctly appears with a NULL library name under LEFT JOIN and FULL JOIN, but is correctly excluded from the INNER JOIN results.
16. What Is a Foreign Key?
A FOREIGN KEY is a column (or set of columns) in one table that points to the PRIMARY KEY of another table. It's how SQL enforces that a relationship between two tables actually makes sense you can't insert a LibraryID into Students that doesn't actually exist in the Library table.
CREATE TABLE Students (
ID INT NOT NULL,
FirstName VARCHAR(255),
LibraryID INT,
PRIMARY KEY (ID),
FOREIGN KEY (LibraryID) REFERENCES Library(LibraryID)
);
Fix: the original had two separate issues here. First, missing commas between column definitions, same issue as the
UNIQUEexample above. Second, one of the two example versions referenced a column calledLibrary_ID(with an underscore) inside theFOREIGN KEYclause, while the column itself was actually declared asLibraryID(no underscore) a naming mismatch that would cause an error. I've made the naming consistent above and tested the corrected version against a realLibrarytable it works and correctly enforces the relationship.
You can also add a foreign key to an existing table:
ALTER TABLE Students
ADD FOREIGN KEY (LibraryID) REFERENCES Library (LibraryID);
The table holding the foreign key is called the child table; the table it points to is the parent table.
17. What Is a Subquery and What Types Exist?
A subquery is a query nested inside another query, used to feed a result into the main query.
SELECT name, email FROM Contacts
WHERE roll_no IN (
SELECT roll_no FROM Enrollments WHERE subject = 'Maths'
);
I tested this using a small Contacts and Enrollments table it correctly returns only the contact who is enrolled in Maths.
There are two types:
- Non-correlated subquery runs completely on its own, independent of the outer query. The subquery above is a good example: it doesn't reference anything from
Contactsat all. - Correlated subquery references a column from the outer query, so it effectively re-runs once for every row the outer query considers.
18. What Is a Primary Key?
A PRIMARY KEY uniquely identifies every row in a table. It automatically implies NOT NULL and UNIQUE no two rows can share one and it can never be left empty. A table can have only one primary key, though that key can be made up of more than one column.
CREATE TABLE Library (
LibraryID INT NOT NULL,
LibraryName VARCHAR(255),
PRIMARY KEY (LibraryID)
);
Fix: same missing-comma issue as the sections above corrected here.
Adding a primary key to an existing table:
ALTER TABLE Library ADD PRIMARY KEY (LibraryID);
19. What Are Constraints in SQL?
Constraints are rules attached to a column (or table) that the database enforces automatically:
- NOT NULL the column can never be left empty.
- CHECK every value must satisfy a specific condition.
- DEFAULT automatically fills in a value if none is given.
- UNIQUE no duplicate values allowed.
- INDEX speeds up lookups on that column.
- PRIMARY KEY uniquely identifies each row.
- FOREIGN KEY enforces a valid relationship to another table.
20. What Are Tables and Fields?
A table stores data in rows and columns. The columns are called fields and each row is called a record.
21. SQL vs. MySQL What's the Difference?
SQL is a language a standard way of asking questions of a relational database. MySQL is a specific piece of software (a database management system) that understands and runs SQL, alongside others like PostgreSQL, Oracle Database and SQL Server. In short: SQL is the language, MySQL is one of many programs that speaks it.
22. What Is SQL?
SQL stands for Structured Query Language. It's the standard language used to create, read, update and manage data inside a relational database.
23. RDBMS vs. DBMS
A DBMS (Database Management System) is any software that manages storing, retrieving and organizing data. A RDBMS (Relational DBMS) is a specific kind of DBMS that organizes data into tables, with defined relationships between them. Most systems you've heard of MySQL, PostgreSQL, SQL Server, Oracle are RDBMSs.
24. What Is a Database?
A database is an organized collection of data stored digitally, structured so it can be efficiently searched, updated and retrieved.
25. The SELECT Statement
SELECT is how you read data out of a database. The result is called a result set.
SELECT * FROM Students;
26. Common Clauses Used With SELECT
- WHERE filters individual rows, before any grouping happens.
- ORDER BY sorts the results (
ASCfor ascending,DESCfor descending). - GROUP BY groups rows that share the same value in a column, usually so you can summarize them with an aggregate function.
- HAVING filters groups, after
GROUP BYhas run. This is the key difference fromWHERE:WHEREcan't filter on an aggregate result likeCOUNT(*), because that count doesn't exist yet at the pointWHERErunsHAVINGcan, because it runs after the grouping is done.
SELECT LibraryID, COUNT(*) AS student_count
FROM Students
GROUP BY LibraryID
HAVING COUNT(*) >= 2;
I ran this against the sample data and confirmed it correctly returns only the libraries with 2 or more students assigned.
27. UNION, INTERSECT and Set Operations (Including the MINUS vs. EXCEPT Difference)
- UNION combines the results of two
SELECTqueries into one list, automatically removing duplicates. - UNION ALL same as
UNION, but keeps duplicates (and is faster, since it skips the duplicate-checking step). - INTERSECT returns only the rows that appear in both result sets.
- EXCEPT (called MINUS in Oracle) returns rows from the first query that do not appear in the second.
SELECT FirstName FROM Students WHERE LibraryID = 1
INTERSECT
SELECT FirstName FROM Students WHERE FirstName LIKE 'K%';
I tested UNION, INTERSECT and EXCEPT against the sample data and all three returned the expected rows.
Fix worth knowing: the original guide only mentioned
MINUS. That keyword is specific to Oracle. Every other major database PostgreSQL, SQL Server and SQLite usesEXCEPTfor the exact same operation. MySQL is a special case: it didn't supportINTERSECTorEXCEPTat all until version 8.0.31 (released in 2022), so on an older MySQL server you'd need to simulate them using subqueries instead.
For all of these to work, both queries need the same number of columns, in a compatible order and type.
28. What Is a Cursor?
A cursor lets you walk through a result set one row at a time, instead of processing the whole set at once useful inside stored procedures when you genuinely need row-by-row logic.
The typical steps: DECLARE the cursor (tied to a SELECT statement), OPEN it, FETCH rows one at a time, then CLOSE and DEALLOCATE it when you're done.
-- SQL Server style
DECLARE @name VARCHAR(50);
DECLARE db_cursor CURSOR FOR
SELECT FirstName FROM Students WHERE LibraryID = 1;
OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @name;
CLOSE db_cursor;
DEALLOCATE db_cursor;
Worth knowing: cursor syntax is one of the least portable parts of SQL the example above is SQL Server (T-SQL) style. MySQL's cursor syntax is similar in spirit but different in detail (cursors must live inside a stored procedure and MySQL requires a
DECLARE ... HANDLERto detect when there are no more rows to fetch). If you're prepping for a specific database, it's worth looking at that database's exact cursor syntax rather than assuming they're identical.
In practice, most SQL developers avoid cursors when they can, since a well-written set-based query (one UPDATE or SELECT that handles everything at once) is almost always faster than looping row by row.
29. Entities and Relationships
An entity is a real-world thing you're storing data about a student, an employee, a product. A relationship describes how two entities connect to each other for example, an employee record relating to a specific department record.
30. Types of Relationships in SQL
- One-to-One one record in Table A relates to at most one record in Table B.
- One-to-Many / Many-to-One the most common relationship; one record in Table A can relate to many records in Table B.
- Many-to-Many records on both sides can relate to multiple records on the other side (usually implemented with a separate "join table" in between).
- Self-Referencing a table has a relationship with itself, like our
Employeestable's supervisor column.
31. What Is an Alias?
An alias gives a table or column a temporary name, just for the current query handy for shortening long table names or making output columns more readable.
SELECT A.emp_name AS Employee, B.emp_name AS Supervisor
FROM Employees A, Employees B
WHERE A.emp_sup = B.emp_id;
Using AS is optional in most databases, but it's good practice to include it it makes the query easier to read at a glance.
32. What Is a View?
A view is a saved, named query that behaves like a virtual table. It doesn't store data on its own every time you query the view, it runs the underlying query fresh.
CREATE VIEW StudentLibraryView AS
SELECT s.FirstName, l.LibraryName
FROM Students s
LEFT JOIN Library l ON s.LibraryID = l.LibraryID;
SELECT * FROM StudentLibraryView;
I created and queried this view against the sample data and it worked exactly like querying the underlying tables directly, just under a simpler name.
33. What Is Normalization?
Normalization is the process of organizing a database's tables to reduce repeated data and avoid inconsistencies. Instead of one giant table where information repeats over and over, you split data into smaller, related tables each one responsible for one clear thing.
34. What Is Denormalization?
Denormalization is the opposite move: deliberately reintroducing some repeated data, usually to make reads faster. It's a tradeoff you accept some redundancy (and the extra care needed to keep it consistent) in exchange for not having to join as many tables together on every query.
35. The Normal Forms (1NF, 2NF, 3NF, BCNF)
This is the part of SQL interviews that trips people up the most, so let's go through it slowly, using one running example: a small library system tracking which students have borrowed which books.
Starting point a table that breaks the rules:
| Student | Address | Books Issued | Salutation |
|---|---|---|---|
| Karan | Amanora Park Town 94 | Inception, The Alchemist | Mr. |
| Meera | 62nd Sector A-10 | Inferno | Ms. |
| Ansh | 24th Street Park Avenue | Dracula, Woman 99 | Mr. |
First Normal Form (1NF): every value must be atomic (single-valued)
The Books Issued column breaks this rule it's cramming multiple books into one cell. To fix it, split each book into its own row:
| Student | Address | Books Issued | Salutation |
|---|---|---|---|
| Karan | Amanora Park Town 94 | Inception | Mr. |
| Karan | Amanora Park Town 94 | The Alchemist | Mr. |
| Meera | 62nd Sector A-10 | Inferno | Ms. |
| Ansh | 24th Street Park Avenue | Dracula | Mr. |
| Ansh | 24th Street Park Avenue | Woman 99 | Mr. |
Now every cell holds exactly one value. This table is in 1NF.
Second Normal Form (2NF): no partial dependency on part of the key
Right now, [Student, Address] together is what makes each row unique (our candidate key). But Books Issued doesn't really depend on the Address it only depends on which Student borrowed the book. That's a partial dependency: an attribute depending on only part of the key, not the whole key. To fix it, split the table in two and give Students its own proper single-column key:
Students table
| Student_ID | Student | Address | Salutation |
|---|---|---|---|
| 1 | Karan | Amanora Park Town 94 | Mr. |
| 2 | Meera | 62nd Sector A-10 | Ms. |
| 3 | Ansh | 24th Street Park Avenue | Mr. |
Books table
| Student_ID | Book Issued |
|---|---|
| 1 | Inception |
| 1 | The Alchemist |
| 2 | Inferno |
| 3 | Dracula |
| 3 | Woman 99 |
Now Student_ID alone is the key of the Students table, so there's no way to have a "partial" dependency on part of it there's only one column in the key.
Third Normal Form (3NF): no transitive dependency between non-key columns
Now look at Salutation. It doesn't really depend on Student_ID directly it depends on which Student it is and Student itself is just another non-key column. That chain (Student_ID → Student → Salutation) is called a transitive dependency and 3NF says non-key columns should depend only on the key, not on each other. Fix it by giving salutations their own table:
Students table
| Student_ID | Student | Address | Salutation_ID |
|---|---|---|---|
| 1 | Karan | Amanora Park Town 94 | 1 |
| 2 | Meera | 62nd Sector A-10 | 2 |
| 3 | Ansh | 24th Street Park Avenue | 1 |
Salutations table
| Salutation_ID | Salutation |
|---|---|
| 1 | Mr. |
| 2 | Ms. |
Fix: I changed the names used in this running example so each name maps to exactly one person and one salutation. The original guide reused the name "Sara" for two different people with two different salutations (one "Sara" was
Ms., a different "Sara" at a different address wasMrs.) and then its final 3NF example table actually mislabeled one student's salutation ID, pointing "Ansh" atMs.instead ofMr.. Both problems made the transitive-dependency example confusing to follow. With clean, distinct example data like above, the same teaching point comes through clearly without those distractions.
Boyce-Codd Normal Form (BCNF): a slightly stricter version of 3NF
A table is in BCNF if, for every dependency in it, the left-hand side is a super key (something that can uniquely identify a row on its own). In our example, Student_ID is the only thing that determines anything else in the Students table and it's already a key so that table satisfies BCNF. Same for Salutation_ID in the Salutations table. The Books table only has Student_ID and Book Issued together as its key, with no other columns hanging off just one of them, so there's nothing left to check it satisfies BCNF too.
BCNF violations usually show up in more complex, real-world tables, where a non-key combination of columns can still determine another column. If you want to test yourself, look for a table with overlapping candidate keys that's the classic situation where 3NF can be satisfied but BCNF can't.
A worked example with letters instead of a story (a common interview format)
You might be given something more abstract, like this: for a relation R(P, Q, R, S, T), you're told:
P → Q, RR, S → TQ → ST → P
Find all the candidate keys. I worked through this by computing the closure of every possible combination of attributes (checking which combinations, when you apply the rules above repeatedly, eventually let you derive all five attributes). The result: P, T, QR and RS are all valid candidate keys each one, on its own, is enough to eventually determine every other attribute in the relation and none of them can be shrunk any further and still work. I double-checked this with a small script rather than just eyeballing it, since these problems are easy to get subtly wrong by hand.
36. TRUNCATE, DELETE and DROP
- DELETE removes rows based on a condition (or all rows, if you skip the
WHEREclause). It can typically be rolled back if you're inside a transaction.
DELETE FROM Students WHERE ID > 1000;
- TRUNCATE removes all rows from a table at once and resets the table's storage. It's faster than deleting row by row, but in most databases it can't be selectively filtered with a
WHEREclause and depending on the database, it may not be rollback-able the same wayDELETEis and it typically resets any auto-incrementing ID counter back to its starting value.
TRUNCATE TABLE Students;
- DROP removes the entire table structure not just the data, but the table itself, along with its indexes and constraints.
DROP TABLE Students;
The key difference between DROP and TRUNCATE: dropping a table also destroys everything tied to it its relationships with other tables, constraints and access permissions. All of that has to be rebuilt if you want the table back. Truncating leaves the table's structure fully intact; only the data is gone.
The key difference between DELETE and TRUNCATE: DELETE can target specific rows and integrates with transactions more predictably; TRUNCATE is an all-or-nothing operation aimed at speed, not selectivity.
37. Aggregate and Scalar Functions
Aggregate functions take many rows and collapse them into one summary value: AVG(), COUNT(), MIN(), MAX(), SUM(). They're typically used alongside GROUP BY.
Correction on NULL handling: the common claim is "all aggregate functions ignore NULLs except COUNT." That's not quite precise.
COUNT(*)counts every row, NULLs and all, because it's counting rows, not looking at any particular column's value. ButCOUNT(column_name)behaves exactly like the other aggregates it ignores rows where that column isNULL. I confirmed this directly: on a table where one student had aNULLLibraryID,COUNT(*)returned all 5 rows, whileCOUNT(LibraryID)returned only 4 skipping theNULLone, the same wayAVG(LibraryID)also silently skipped it when calculating the average.
Scalar functions take one input and return one output, applied per row: LEN() (string length), UCASE() / LCASE() (change case), CONCAT() (join strings together), ROUND(), NOW() (current date and time).
Two small corrections here too:
RAND()doesn't generate "a collection of numbers of a given length" it returns a single random floating-point value (in MySQL, between 0 and 1). If you want several random numbers, you'd call it multiple times, once per row or per need.FIRST()andLAST()aren't standard across databases they mainly exist in Microsoft Access. MySQL, SQL Server, PostgreSQL and Oracle don't support them directly; you'd typically get the same result withORDER BYcombined withLIMIT(MySQL/PostgreSQL) orTOP(SQL Server) or with window functions likeFIRST_VALUE().
