SQL Command Categories
SQL statements are grouped into five categories by purpose.
Concept
SQL statements are grouped into five categories by purpose.
Data Definition Language Define and change database structure (schema objects)
CREATE, ALTER, DROP, TRUNCATE, RENAME, COMMENT Data Manipulation Language Change data inside tables INSERT, UPDATE, DELETE, MERGE Data Query Language Data Control Language Transaction Control Language
COMMIT, ROLLBACK, SAVEPOINT, SET TRANSACTION Some textbooks put SELECT inside DML, since it "manipulates" data by reading it. Both classifications are accepted in interviews; mention both.
SQL
┌──────────┬───────────┼───────────┬──────────┐
DDL DML DQL DCL TCL
(structure) (data change) (query) (permissions) (transactions)
CREATE INSERT SELECT GRANT COMMIT
ALTER UPDATE REVOKE ROLLBACK
DROP DELETE SAVEPOINT
TRUNCATE MERGE (BEGIN / START TRANSACTION)
RENAME
(COMMENT)Why It Matters
Knowing the category tells you the side effects of a statement: DDL changes structure (and in some databases auto-commits); DML changes data (and can be rolled back inside a transaction).
Permissions are often granted per category (e.g., analysts get DQL only).
Interviewers often ask "Is TRUNCATE DDL or DML?" (DDL) and "Can DDL be rolled back?" (depends on the DBMS).
Syntax
DDL — Data Definition Language DML — Data Manipulation Language
MySQL and SQLite equivalents of MERGE ("upsert"):
DQL — Data Query Language DCL — Data Control Language TCL — Transaction Control Language
-- CREATE: make a new object
CREATE TABLE suppliers (
supplier_id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL
);
-- ALTER: change an existing object
ALTER TABLE suppliers ADD phone VARCHAR(20);
-- DROP: remove an object entirely (structure + data)
DROP TABLE suppliers;
-- TRUNCATE: remove all rows, keep structure
TRUNCATE TABLE audit_log;
-- RENAME (syntax varies by DBMS)
ALTER TABLE suppliers RENAME TO vendors; -- PostgreSQL, SQLite, Oracle, MySQL
RENAME TABLE suppliers TO vendors; -- MySQL
EXEC sp_rename 'suppliers', 'vendors'; -- SQL Server-- INSERT: add rows
INSERT INTO products (product_id, product_name, category, price, stock)
VALUES (107, 'Keyboard', 'Electronics', 1500.00, 80);
-- UPDATE: change existing rows
UPDATE products
SET price = 1400.00
WHERE product_id = 107;
-- DELETE: remove rows
DELETE FROM products
WHERE product_id = 107;
-- MERGE: insert or update depending on whether a match exists (SQL:2003)
-- Supported: SQL Server, Oracle, PostgreSQL 15+, Db2. Not supported in MySQL/SQLite.
MERGE INTO products AS t
USING (VALUES (102, 'Mouse', 'Electronics', 750.00, 250)) AS s(product_id, product_name, category, price, stock)
ON t.product_id = s.product_id
WHEN MATCHED THEN
UPDATE SET price = s.price, stock = s.stock
WHEN NOT MATCHED THEN
INSERT (product_id, product_name, category, price, stock)
VALUES (s.product_id, s.product_name, s.category, s.price, s.stock);-- MySQL
INSERT INTO products (product_id, product_name, category, price, stock)
VALUES (102, 'Mouse', 'Electronics', 750.00, 250)
ON DUPLICATE KEY UPDATE price = VALUES(price), stock = VALUES(stock);
-- (MySQL 8.0.20+ prefers an alias: ... VALUES (...) AS new
-- ON DUPLICATE KEY UPDATE price = new.price, stock = new.stock;)
-- PostgreSQL and SQLite (3.24+)
INSERT INTO products (product_id, product_name, category, price, stock)
VALUES (102, 'Mouse', 'Electronics', 750.00, 250)
ON CONFLICT (product_id)
DO UPDATE SET price = EXCLUDED.price, stock = EXCLUDED.stock;SELECT product_name, price
FROM products
WHERE category = 'Electronics'
ORDER BY price DESC;GRANT SELECT, INSERT ON orders TO sales_app;
REVOKE INSERT ON orders FROM sales_app;BEGIN; -- PostgreSQL, SQLite (START TRANSACTION in MySQL; BEGIN TRANSACTION in SQL Server)
UPDATE products SET stock = stock - 1 WHERE product_id = 101;
SAVEPOINT after_stock;
INSERT INTO orders (order_id, customer_id, order_date, status, total_amount)
VALUES (1007, 5, DATE '2026-03-15', 'PENDING', 75000.00);
ROLLBACK TO SAVEPOINT after_stock; -- undo only the INSERT
COMMIT; -- make the stock change permanentExample
DELETE vs TRUNCATE vs DROP (in detail) These three are among the most frequently asked interview questions.
Selected rows (WHERE) or all rows Entire table: rows, structure, indexes, constraints, triggers, privileges Table structure afterwards Speed on large tables Slow (row-by-row, logs each row) Very fast (deallocates data pages) Every deleted row is logged Minimal (page deallocation logged) Fires DELETE triggers
No (row triggers do not fire; PostgreSQL has TRUNCATE triggers) Resets identity / auto-increment
Yes in MySQL, SQL Server; PostgreSQL only with RESTART IDENTITY Yes (inside a transaction)
PostgreSQL & SQL Server: yes inside a transaction. MySQL & Oracle: no (implicit commit)
PostgreSQL & SQL Server: yes inside a transaction. MySQL & Oracle: no (Oracle has FLASHBACK / recycle bin) Works if referenced by a foreign key Yes (if no child rows violate)
Usually blocked (PostgreSQL needs CASCADE; SQL Server forbids)
Blocked unless constraints dropped or CASCADE used Table lock (schema lock) Not immediately (space reused later) Remove specific records Empty staging/log tables Remove the object permanently
Mnemonic: DELETE removes some or all rows; TRUNCATE removes all rows; DROP removes the table.
-- DELETE: remove selected rows (or all rows if no WHERE)
DELETE FROM order_items WHERE order_id = 1004;
DELETE FROM audit_log; -- removes all rows, one by one
-- TRUNCATE: remove all rows quickly, keep the table
TRUNCATE TABLE audit_log;
-- DROP: remove the table itself
DROP TABLE audit_log;Expected Result
After running the TCL example above, products.stock for product 101 is 14 (reduced by 1) and order 1007 does not exist, because the INSERT was rolled back to the savepoint before COMMIT.
Common Mistakes
Running DELETE FROM table; without WHERE and deleting everything. Always write the WHERE first, or run a SELECT with the same WHERE before deleting.
Assuming TRUNCATE can be rolled back everywhere. In MySQL and Oracle it commits immediately.
Assuming DDL is transactional. In MySQL and Oracle, CREATE/ALTER/DROP cause an implicit commit of the current transaction. PostgreSQL and SQL Server support transactional DDL.
Using MERGE in MySQL (not supported); use INSERT ... ON DUPLICATE KEY UPDATE.
Expecting DELETE to reset an auto-increment counter.
Best Practices
Before UPDATE or DELETE, run the equivalent SELECT to confirm affected rows.
Wrap destructive DML in a transaction so you can roll back.
Restrict DDL and DCL privileges to administrators and migration tools.
Manage schema changes with versioned migration tools (Flyway, Liquibase, Alembic, Prisma Migrate) instead of ad-hoc DDL in production.
Interview Relevance
Guaranteed questions: "Categories of SQL commands?", "DELETE vs TRUNCATE vs DROP?", "Is TRUNCATE DDL or DML?", "Can TRUNCATE be rolled back?", "What is MERGE / upsert?".
Practice Questions
Classify each statement: GRANT, TRUNCATE, MERGE, SAVEPOINT, ALTER, SELECT.
You need to empty a 50-million-row staging table every night. Which command do you use and why?
Write a statement that deletes only cancelled orders.
Why might TRUNCATE TABLE customers; fail even though the table exists?
Write an upsert for the products table in PostgreSQL that sets stock to 50 for product 104, inserting it if missing.