A comprehensive SQL reference guide for database operations, query optimization, and interview preparation.
Command | Purpose | Syntax | Example |
---|---|---|---|
CREATE |
Create database objects | CREATE TABLE/DATABASE/INDEX... |
CREATE TABLE Users (ID INT, Name VARCHAR(50)) |
ALTER |
Modify existing objects | ALTER TABLE table_name ADD/DROP/MODIFY |
ALTER TABLE Users ADD Email VARCHAR(100) |
DROP |
Delete database objects | DROP TABLE/DATABASE/INDEX... |
DROP TABLE Users |
TRUNCATE |
Remove all table data | TRUNCATE TABLE table_name |
TRUNCATE TABLE Users |
COMMENT |
Add comments to objects | COMMENT ON TABLE/COLUMN... |
COMMENT ON TABLE Users IS 'User information' |
RENAME |
Rename database objects | RENAME TABLE old_name TO new_name |
RENAME TABLE Users TO Customers |
Command | Purpose | Syntax | Example |
---|---|---|---|
SELECT |
Retrieve data from tables | SELECT columns FROM table WHERE condition |
SELECT Name, Email FROM Users WHERE Age > 18 |
INSERT |
Add new records | INSERT INTO table (columns) VALUES (values) |
INSERT INTO Users (Name, Age) VALUES ('John', 25) |
UPDATE |
Modify existing records | UPDATE table SET column = value WHERE condition |
UPDATE Users SET Age = 26 WHERE Name = 'John' |
DELETE |
Remove specific records | DELETE FROM table WHERE condition |
DELETE FROM Users WHERE Age < 18 |
MERGE |
Conditional insert/update | MERGE target USING source ON condition |
MERGE Users USING NewUsers ON Users.ID = NewUsers.ID |
CALL |
Execute stored procedures | CALL procedure_name(parameters) |
CALL GetUsersByAge(25) |
Command | Purpose | Syntax | Example |
---|---|---|---|
GRANT |
Give permissions to users | GRANT privilege ON object TO user |
GRANT SELECT ON Users TO john_user |
REVOKE |
Remove permissions | REVOKE privilege ON object FROM user |
REVOKE INSERT ON Users FROM john_user |
DENY |
Explicitly deny permissions | DENY privilege ON object TO user |
DENY DELETE ON Users TO intern_user |
Command | Purpose | Syntax | Example |
---|---|---|---|
BEGIN |
Start a transaction | BEGIN TRANSACTION |
BEGIN TRANSACTION UserUpdate |
COMMIT |
Save all changes | COMMIT |
COMMIT |
ROLLBACK |
Undo all changes | ROLLBACK |
ROLLBACK TO SavePoint1 |
SAVEPOINT |
Create a checkpoint | SAVEPOINT savepoint_name |
SAVEPOINT BeforeUpdate |
RELEASE |
Remove a savepoint | RELEASE SAVEPOINT savepoint_name |
RELEASE SAVEPOINT BeforeUpdate |
SET TRANSACTION |
Set transaction properties | SET TRANSACTION ISOLATION LEVEL... |
SET TRANSACTION ISOLATION LEVEL READ COMMITTED |
JOIN Type | Purpose | Syntax | Result |
---|---|---|---|
INNER JOIN |
Returns matching records from both tables | SELECT * FROM A INNER JOIN B ON A.id = B.id |
Only rows with matches in both tables |
LEFT JOIN |
Returns all records from left table | SELECT * FROM A LEFT JOIN B ON A.id = B.id |
All left table rows + matching right table rows |
RIGHT JOIN |
Returns all records from right table | SELECT * FROM A RIGHT JOIN B ON A.id = B.id |
All right table rows + matching left table rows |
FULL OUTER JOIN |
Returns all records from both tables | SELECT * FROM A FULL OUTER JOIN B ON A.id = B.id |
All rows from both tables |
CROSS JOIN |
Cartesian product of both tables | SELECT * FROM A CROSS JOIN B |
Every row from A paired with every row from B |
SELF JOIN |
Join table with itself | SELECT * FROM A a1 JOIN A a2 ON a1.mgr_id = a2.id |
Compare rows within the same table |
NATURAL JOIN |
Join on columns with same name | SELECT * FROM A NATURAL JOIN B |
Automatic join on matching column names |
Employee Table | Department Table |
---|---|
ID | Name | DeptID | DeptID | DeptName |
1 | John | 10 | 10 | IT |
2 | Jane | 20 | 20 | HR |
3 | Bob | NULL | 30 | Finance |
JOIN Type | Query | Result Rows |
---|---|---|
INNER JOIN | SELECT e.Name, d.DeptName FROM Employee e INNER JOIN Department d ON e.DeptID = d.DeptID |
John-IT, Jane-HR |
LEFT JOIN | SELECT e.Name, d.DeptName FROM Employee e LEFT JOIN Department d ON e.DeptID = d.DeptID |
John-IT, Jane-HR, Bob-NULL |
RIGHT JOIN | SELECT e.Name, d.DeptName FROM Employee e RIGHT JOIN Department d ON e.DeptID = d.DeptID |
John-IT, Jane-HR, NULL-Finance |
FULL OUTER | SELECT e.Name, d.DeptName FROM Employee e FULL OUTER JOIN Department d ON e.DeptID = d.DeptID |
John-IT, Jane-HR, Bob-NULL, NULL-Finance |
Category | Type | Description | Example |
---|---|---|---|
Numeric | TINYINT |
0 to 255 | TINYINT |
SMALLINT |
-32,768 to 32,767 | SMALLINT |
|
INT |
-2,147,483,648 to 2,147,483,647 | INT |
|
BIGINT |
Very large integers | BIGINT |
|
DECIMAL(p,s) |
Fixed precision and scale | DECIMAL(10,2) |
|
NUMERIC(p,s) |
Same as DECIMAL | NUMERIC(15,4) |
|
FLOAT(n) |
Floating point number | FLOAT(24) |
|
REAL |
Single precision floating point | REAL |
|
MONEY |
Currency values | MONEY |
|
SMALLMONEY |
Small currency values | SMALLMONEY |
|
String | CHAR(n) |
Fixed length string | CHAR(10) |
VARCHAR(n) |
Variable length string | VARCHAR(255) |
|
VARCHAR(MAX) |
Large variable length string | VARCHAR(MAX) |
|
NCHAR(n) |
Fixed length Unicode | NCHAR(10) |
|
NVARCHAR(n) |
Variable length Unicode | NVARCHAR(255) |
|
NVARCHAR(MAX) |
Large Unicode string | NVARCHAR(MAX) |
|
TEXT |
Large text data (deprecated) | TEXT |
|
NTEXT |
Large Unicode text (deprecated) | NTEXT |
|
Date/Time | DATE |
Date only | DATE |
TIME |
Time only | TIME |
|
DATETIME |
Date and time | DATETIME |
|
DATETIME2 |
Extended date and time | DATETIME2 |
|
SMALLDATETIME |
Small date and time | SMALLDATETIME |
|
DATETIMEOFFSET |
Date and time with timezone | DATETIMEOFFSET |
|
Binary | BINARY(n) |
Fixed length binary | BINARY(8) |
VARBINARY(n) |
Variable length binary | VARBINARY(255) |
|
VARBINARY(MAX) |
Large binary data | VARBINARY(MAX) |
|
IMAGE |
Large binary data (deprecated) | IMAGE |
|
Other | BIT |
Boolean (0 or 1) | BIT |
UNIQUEIDENTIFIER |
Globally unique identifier | UNIQUEIDENTIFIER |
|
XML |
XML data | XML |
|
CURSOR |
Reference to cursor | CURSOR |
|
TABLE |
Table data type | TABLE |
|
SQL_VARIANT |
Can store various data types | SQL_VARIANT |
Category | Operator | Description | Example |
---|---|---|---|
Arithmetic | + |
Addition | SELECT 5 + 3 |
- |
Subtraction | SELECT 10 - 4 |
|
* |
Multiplication | SELECT 6 * 7 |
|
/ |
Division | SELECT 15 / 3 |
|
% |
Modulo (remainder) | SELECT 17 % 5 |
|
Comparison | = |
Equal | WHERE Age = 25 |
<> or != |
Not equal | WHERE Age <> 25 |
|
< |
Less than | WHERE Age < 30 |
|
<= |
Less than or equal | WHERE Age <= 30 |
|
> |
Greater than | WHERE Age > 18 |
|
>= |
Greater than or equal | WHERE Age >= 18 |
|
Logical | AND |
Logical AND | WHERE Age > 18 AND Age < 65 |
OR |
Logical OR | WHERE City = 'NYC' OR City = 'LA' |
|
NOT |
Logical NOT | WHERE NOT Age = 25 |
|
IN |
Value in list | WHERE City IN ('NYC', 'LA') |
|
NOT IN |
Value not in list | WHERE City NOT IN ('NYC', 'LA') |
|
BETWEEN |
Value in range | WHERE Age BETWEEN 18 AND 65 |
|
LIKE |
Pattern matching | WHERE Name LIKE 'John%' |
|
IS NULL |
Check for NULL | WHERE Email IS NULL |
|
IS NOT NULL |
Check for not NULL | WHERE Email IS NOT NULL |
|
EXISTS |
Subquery returns rows | WHERE EXISTS (SELECT ...) |
|
Assignment | = |
Assign value | SET @var = 10 |
+= |
Add and assign | SET @var += 5 |
|
-= |
Subtract and assign | SET @var -= 3 |
|
*= |
Multiply and assign | SET @var *= 2 |
|
/= |
Divide and assign | SET @var /= 4 |
|
%= |
Modulo and assign | SET @var %= 3 |
Function | Description | Example |
---|---|---|
LEN(string) |
Returns string length | SELECT LEN('Hello') β 5 |
LEFT(string, n) |
Returns left n characters | SELECT LEFT('Hello', 3) β 'Hel' |
RIGHT(string, n) |
Returns right n characters | SELECT RIGHT('Hello', 3) β 'llo' |
SUBSTRING(string, start, length) |
Returns substring | SELECT SUBSTRING('Hello', 2, 3) β 'ell' |
UPPER(string) |
Converts to uppercase | SELECT UPPER('hello') β 'HELLO' |
LOWER(string) |
Converts to lowercase | SELECT LOWER('HELLO') β 'hello' |
LTRIM(string) |
Removes leading spaces | SELECT LTRIM(' Hello') β 'Hello' |
RTRIM(string) |
Removes trailing spaces | SELECT RTRIM('Hello ') β 'Hello' |
TRIM(string) |
Removes leading/trailing spaces | SELECT TRIM(' Hello ') β 'Hello' |
REPLACE(string, old, new) |
Replace substring | SELECT REPLACE('Hello', 'ell', 'i') β 'Hio' |
REVERSE(string) |
Reverse string | SELECT REVERSE('Hello') β 'olleH' |
CHARINDEX(substring, string) |
Find substring position | SELECT CHARINDEX('ell', 'Hello') β 2 |
PATINDEX(pattern, string) |
Find pattern position | SELECT PATINDEX('%ell%', 'Hello') β 2 |
CONCAT(string1, string2, ...) |
Concatenate strings | SELECT CONCAT('Hello', ' ', 'World') |
STRING_AGG(expression, separator) |
Aggregate strings | SELECT STRING_AGG(Name, ', ') |
FORMAT(value, format) |
Format value as string | SELECT FORMAT(123.45, 'C') β 123γγ«.45 |
STUFF(string, start, length, new) |
Insert string | SELECT STUFF('Hello', 2, 2, 'i') β 'Hilo' |
REPLICATE(string, count) |
Repeat string | SELECT REPLICATE('Hi', 3) β 'HiHiHi' |
SPACE(count) |
Generate spaces | SELECT 'A' + SPACE(5) + 'B' β 'A B' |
ASCII(character) |
Get ASCII value | SELECT ASCII('A') β 65 |
CHAR(ascii_code) |
Get character from ASCII | SELECT CHAR(65) β 'A' |
UNICODE(character) |
Get Unicode value | SELECT UNICODE('A') β 65 |
NCHAR(unicode) |
Get Unicode character | SELECT NCHAR(65) β 'A' |
Function | Description | Example |
---|---|---|
GETDATE() |
Current date and time | SELECT GETDATE() |
GETUTCDATE() |
Current UTC date and time | SELECT GETUTCDATE() |
SYSDATETIME() |
Current system date and time | SELECT SYSDATETIME() |
CURRENT_TIMESTAMP |
Current timestamp | SELECT CURRENT_TIMESTAMP |
DATEADD(part, number, date) |
Add time interval | SELECT DATEADD(DAY, 7, GETDATE()) |
DATEDIFF(part, date1, date2) |
Difference between dates | SELECT DATEDIFF(DAY, '2023-01-01', GETDATE()) |
DATEPART(part, date) |
Extract date part | SELECT DATEPART(YEAR, GETDATE()) |
DATENAME(part, date) |
Get date part name | SELECT DATENAME(MONTH, GETDATE()) |
YEAR(date) |
Extract year | SELECT YEAR(GETDATE()) |
MONTH(date) |
Extract month | SELECT MONTH(GETDATE()) |
DAY(date) |
Extract day | SELECT DAY(GETDATE()) |
ISDATE(expression) |
Check if valid date | SELECT ISDATE('2023-13-01') β 0 |
FORMAT(date, format) |
Format date | SELECT FORMAT(GETDATE(), 'yyyy-MM-dd') |
PARSE(string AS datetime) |
Parse string to date | SELECT PARSE('01/01/2023' AS datetime) |
TRY_PARSE(string AS datetime) |
Safe parse to date | SELECT TRY_PARSE('invalid' AS datetime) |
CONVERT(datatype, expression, style) |
Convert date format | SELECT CONVERT(varchar, GETDATE(), 101) |
CAST(expression AS datatype) |
Cast to date type | SELECT CAST('2023-01-01' AS datetime) |
EOMONTH(date, months) |
End of month | SELECT EOMONTH(GETDATE(), 0) |
DATEFROMPARTS(year, month, day) |
Create date from parts | SELECT DATEFROMPARTS(2023, 1, 1) |
TIMEFROMPARTS(hour, minute, second, fractions, precision) |
Create time | SELECT TIMEFROMPARTS(14, 30, 0, 0, 0) |
Function | Description | Example |
---|---|---|
ABS(number) |
Absolute value | SELECT ABS(-5) β 5 |
CEILING(number) |
Round up to integer | SELECT CEILING(4.3) β 5 |
FLOOR(number) |
Round down to integer | SELECT FLOOR(4.7) β 4 |
ROUND(number, decimals) |
Round to decimals | SELECT ROUND(4.567, 2) β 4.57 |
POWER(base, exponent) |
Raise to power | SELECT POWER(2, 3) β 8 |
SQRT(number) |
Square root | SELECT SQRT(16) β 4 |
SQUARE(number) |
Square of number | SELECT SQUARE(5) β 25 |
EXP(number) |
e raised to power | SELECT EXP(1) β 2.718... |
LOG(number) |
Natural logarithm | SELECT LOG(2.718) β 1 |
LOG10(number) |
Base-10 logarithm | SELECT LOG10(100) β 2 |
SIN(angle) |
Sine | SELECT SIN(PI()/2) β 1 |
COS(angle) |
Cosine | SELECT COS(0) β 1 |
TAN(angle) |
Tangent | SELECT TAN(0) β 0 |
PI() |
Pi constant | SELECT PI() β 3.14159... |
RAND(seed) |
Random number 0-1 | SELECT RAND() |
SIGN(number) |
Sign of number | SELECT SIGN(-5) β -1 |
DEGREES(radians) |
Convert to degrees | SELECT DEGREES(PI()) β 180 |
RADIANS(degrees) |
Convert to radians | SELECT RADIANS(180) β 3.14159... |
Function | Description | Example |
---|---|---|
COUNT(*) |
Count all rows | SELECT COUNT(*) FROM Employees |
COUNT(column) |
Count non-NULL values | SELECT COUNT(Email) FROM Employees |
COUNT(DISTINCT column) |
Count unique values | SELECT COUNT(DISTINCT Department) FROM Employees |
SUM(column) |
Sum of values | SELECT SUM(Salary) FROM Employees |
AVG(column) |
Average of values | SELECT AVG(Salary) FROM Employees |
MIN(column) |
Minimum value | SELECT MIN(Salary) FROM Employees |
MAX(column) |
Maximum value | SELECT MAX(Salary) FROM Employees |
STDEV(column) |
Standard deviation | SELECT STDEV(Salary) FROM Employees |
VAR(column) |
Variance | SELECT VAR(Salary) FROM Employees |
STRING_AGG(column, separator) |
Concatenate strings | SELECT STRING_AGG(Name, ', ') FROM Employees |
CHECKSUM_AGG(column) |
Checksum of values | SELECT CHECKSUM_AGG(ID) FROM Employees |
Function | Description | Example |
---|---|---|
CAST(expression AS datatype) |
Convert data type | SELECT CAST('123' AS INT) |
CONVERT(datatype, expression, style) |
Convert with style | SELECT CONVERT(VARCHAR, GETDATE(), 101) |
TRY_CAST(expression AS datatype) |
Safe cast | SELECT TRY_CAST('abc' AS INT) β NULL |
TRY_CONVERT(datatype, expression) |
Safe convert | SELECT TRY_CONVERT(INT, 'abc') β NULL |
PARSE(string AS datatype USING culture) |
Parse string | SELECT PARSE('123γγ«.45' AS MONEY USING 'en-US') |
TRY_PARSE(string AS datatype) |
Safe parse | SELECT TRY_PARSE('abc' AS INT) β NULL |
STR(number, length, decimals) |
Number to string | SELECT STR(123.456, 8, 2) β ' 123.46' |
FORMAT(value, format, culture) |
Format value | SELECT FORMAT(123456.789, 'C', 'en-US') |
Function | Description | Example |
---|---|---|
CASE WHEN...THEN...ELSE...END |
Conditional logic | SELECT CASE WHEN Age >= 18 THEN 'Adult' ELSE 'Minor' END |
IIF(condition, true_value, false_value) |
Inline IF | SELECT IIF(Age >= 18, 'Adult', 'Minor') |
ISNULL(expression, replacement) |
Replace NULL | SELECT ISNULL(Email, 'No Email') |
NULLIF(expression1, expression2) |
Return NULL if equal | SELECT NULLIF(Division, 0) |
COALESCE(expression1, expression2, ...) |
First non-NULL | SELECT COALESCE(Phone, Mobile, 'No Contact') |
CHOOSE(index, value1, value2, ...) |
Choose by index | SELECT CHOOSE(2, 'First', 'Second', 'Third') β 'Second' |
Function | Description | Example |
---|---|---|
@@VERSION |
SQL Server version | SELECT @@VERSION |
@@SERVERNAME |
Server name | SELECT @@SERVERNAME |
@@SPID |
Session ID | SELECT @@SPID |
USER_NAME() |
Current user | SELECT USER_NAME() |
SYSTEM_USER |
System user | SELECT SYSTEM_USER |
SUSER_NAME() |
Login name | SELECT SUSER_NAME() |
DB_NAME() |
Database name | SELECT DB_NAME() |
DB_ID() |
Database ID | SELECT DB_ID() |
OBJECT_ID(object_name) |
Object ID | SELECT OBJECT_ID('Employees') |
OBJECT_NAME(object_id) |
Object name | SELECT OBJECT_NAME(123456) |
@@ROWCOUNT |
Rows affected | SELECT @@ROWCOUNT |
@@ERROR |
Last error number | SELECT @@ERROR |
@@IDENTITY |
Last identity value | SELECT @@IDENTITY |
SCOPE_IDENTITY() |
Last identity in scope | SELECT SCOPE_IDENTITY() |
IDENT_CURRENT(table) |
Last identity for table | SELECT IDENT_CURRENT('Employees') |
NEWID() |
Generate GUID | SELECT NEWID() |
NEWSEQUENTIALID() |
Generate sequential GUID | SELECT NEWSEQUENTIALID() |
Function | Description | Example |
---|---|---|
COL_LENGTH(table, column) |
Column length | SELECT COL_LENGTH('Employees', 'FirstName') |
COL_NAME(table_id, column_id) |
Column name | SELECT COL_NAME(OBJECT_ID('Employees'), 1) |
COLUMNPROPERTY(id, column, property) |
Column property | SELECT COLUMNPROPERTY(OBJECT_ID('Employees'), 'ID', 'IsIdentity') |
DATALENGTH(expression) |
Data length in bytes | SELECT DATALENGTH('Hello') β 5 |
INDEX_COL(table, index_id, key_id) |
Index column | SELECT INDEX_COL('Employees', 1, 1) |
INDEXPROPERTY(object_id, index, property) |
Index property | SELECT INDEXPROPERTY(OBJECT_ID('Employees'), 'PK_Employees', 'IsClustered') |
OBJECTPROPERTY(id, property) |
Object property | SELECT OBJECTPROPERTY(OBJECT_ID('Employees'), 'IsTable') |
OBJECTPROPERTYEX(id, property) |
Extended object property | SELECT OBJECTPROPERTYEX(OBJECT_ID('Employees'), 'BaseType') |
SCHEMA_ID(schema_name) |
Schema ID | SELECT SCHEMA_ID('dbo') |
SCHEMA_NAME(schema_id) |
Schema name | SELECT SCHEMA_NAME(1) |
TYPE_ID(type_name) |
Type ID | SELECT TYPE_ID('int') |
TYPE_NAME(type_id) |
Type name | SELECT TYPE_NAME(56) |
Function | Description | Example |
---|---|---|
HAS_PERMS_BY_NAME(securable, type, permission) |
Check permission | SELECT HAS_PERMS_BY_NAME('Employees', 'OBJECT', 'SELECT') |
IS_MEMBER(role) |
Check role membership | SELECT IS_MEMBER('db_owner') |
IS_ROLEMEMBER(role, principal) |
Check role membership | SELECT IS_ROLEMEMBER('db_owner', 'dbo') |
IS_SRVROLEMEMBER(role, login) |
Check server role | SELECT IS_SRVROLEMEMBER('sysadmin', 'sa') |
PERMISSIONS(object_id, column) |
Get permissions | SELECT PERMISSIONS(OBJECT_ID('Employees')) |
USER_ID(user_name) |
User ID | SELECT USER_ID('dbo') |
USER_NAME(user_id) |
User name | SELECT USER_NAME(1) |
SUSER_ID(login_name) |
Login ID | SELECT SUSER_ID('sa') |
SUSER_SNAME(server_user_id) |
Login name | SELECT SUSER_SNAME(1) |
Function | Description | Example |
---|---|---|
ROW_NUMBER() OVER(...) |
Sequential row number | SELECT ROW_NUMBER() OVER(ORDER BY Salary DESC) |
RANK() OVER(...) |
Rank with gaps | SELECT RANK() OVER(ORDER BY Salary DESC) |
DENSE_RANK() OVER(...) |
Rank without gaps | SELECT DENSE_RANK() OVER(ORDER BY Salary DESC) |
NTILE(n) OVER(...) |
Divide into n groups | SELECT NTILE(4) OVER(ORDER BY Salary) |
LAG(column, offset) OVER(...) |
Previous row value | SELECT LAG(Salary, 1) OVER(ORDER BY HireDate) |
LEAD(column, offset) OVER(...) |
Next row value | SELECT LEAD(Salary, 1) OVER(ORDER BY HireDate) |
FIRST_VALUE(column) OVER(...) |
First value in window | SELECT FIRST_VALUE(Salary) OVER(ORDER BY HireDate) |
LAST_VALUE(column) OVER(...) |
Last value in window | SELECT LAST_VALUE(Salary) OVER(ORDER BY HireDate) |
SUM(column) OVER(...) |
Running sum | SELECT SUM(Salary) OVER(ORDER BY HireDate) |
AVG(column) OVER(...) |
Moving average | SELECT AVG(Salary) OVER(ORDER BY HireDate ROWS 2 PRECEDING) |
COUNT(*) OVER(...) |
Running count | SELECT COUNT(*) OVER(ORDER BY HireDate) |
MIN(column) OVER(...) |
Running minimum | SELECT MIN(Salary) OVER(ORDER BY HireDate) |
MAX(column) OVER(...) |
Running maximum | SELECT MAX(Salary) OVER(ORDER BY HireDate) |
Function | Description | Example |
---|---|---|
PERCENT_RANK() OVER(...) |
Percentage rank | SELECT PERCENT_RANK() OVER(ORDER BY Salary) |
CUME_DIST() OVER(...) |
Cumulative distribution | SELECT CUME_DIST() OVER(ORDER BY Salary) |
PERCENTILE_CONT(percentile) WITHIN GROUP(...) |
Continuous percentile | SELECT PERCENTILE_CONT(0.5) WITHIN GROUP(ORDER BY Salary) |
PERCENTILE_DISC(percentile) WITHIN GROUP(...) |
Discrete percentile | SELECT PERCENTILE_DISC(0.5) WITHIN GROUP(ORDER BY Salary) |
Understanding the logical execution order of SQL queries is crucial for writing efficient queries and debugging performance issues.
-
FROM - Identify the tables and join them if needed.
- Example:
FROM Employees e INNER JOIN Departments d ON e.DeptID = d.ID
- Example:
-
ON (for joins) - Apply join conditions.
-
JOIN - Combine rows from tables based on join conditions.
-
WHERE - Filter rows based on conditions.
- Example:
WHERE e.Salary > 50000
- Example:
-
GROUP BY - Group rows for aggregate functions.
- Example:
GROUP BY d.DepartmentName
- Example:
-
HAVING - Filter groups based on aggregate conditions.
- Example:
HAVING COUNT(e.EmployeeID) > 5
- Example:
-
SELECT - Choose columns and compute expressions.
- Example:
SELECT d.DepartmentName, AVG(e.Salary)
- Example:
-
DISTINCT - Remove duplicate rows from the result set.
-
ORDER BY - Sort the results.
- Example:
ORDER BY AVG(e.Salary) DESC
- Example:
-
LIMIT / OFFSET / TOP - Restrict the number of rows returned.
- Example:
LIMIT 10 OFFSET 5
- Example:
SELECT d.DepartmentName, AVG(e.Salary) AS AvgSalary FROM Employees e INNER JOIN Departments d ON e.DeptID = d.ID WHERE e.Salary > 50000 GROUP BY d.DepartmentName HAVING AVG(e.Salary) > 60000 ORDER BY AvgSalary DESC LIMIT 5;
FROM Employees e
JOIN Departments d ON e.DeptID = d.ID
WHERE e.Salary > 50000
GROUP BY d.DepartmentName
HAVING AVG(e.Salary) > 60000
SELECT d.DepartmentName, AVG(e.Salary) AS AvgSalary
ORDER BY AvgSalary DESC
LIMIT 5
- Basic SQL Commands
- Data Types
- Database Operations
- Table Operations
- Data Manipulation
- Query Operations
- Join Operations
- Aggregate Functions
- String Functions
- Date Functions
- Mathematical Functions
- Conditional Statements
- Constraints
- Indexes
- Views
- Stored Procedures
- Triggers
- Transactions
- Advanced Concepts
-- Integer types INT, SMALLINT, BIGINT, TINYINT -- Decimal types DECIMAL(precision, scale) NUMERIC(precision, scale) FLOAT, REAL, DOUBLE -- Example CREATE TABLE Products ( ProductID INT PRIMARY KEY, Price DECIMAL(10,2), Quantity SMALLINT );
-- Fixed length CHAR(n) -- Variable length VARCHAR(n) TEXT -- Example CREATE TABLE Customers ( CustomerID INT PRIMARY KEY, FirstName VARCHAR(50), LastName VARCHAR(50), Description TEXT );
DATE -- YYYY-MM-DD TIME -- HH:MM:SS DATETIME -- YYYY-MM-DD HH:MM:SS TIMESTAMP -- Unix timestamp YEAR -- YYYY -- Example CREATE TABLE Orders ( OrderID INT PRIMARY KEY, OrderDate DATE, OrderTime TIME, CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
CREATE DATABASE CompanyDB;
USE CompanyDB;
DROP DATABASE CompanyDB;
SHOW DATABASES;
CREATE TABLE Employees ( EmployeeID INT PRIMARY KEY AUTO_INCREMENT, FirstName VARCHAR(50) NOT NULL, LastName VARCHAR(50) NOT NULL, Email VARCHAR(100) UNIQUE, HireDate DATE, Salary DECIMAL(10,2), DepartmentID INT, FOREIGN KEY (DepartmentID) REFERENCES Departments(DeptID) );
-- Add column ALTER TABLE Employees ADD COLUMN Phone VARCHAR(15); -- Modify column ALTER TABLE Employees MODIFY COLUMN Salary DECIMAL(12,2); -- Drop column ALTER TABLE Employees DROP COLUMN Phone; -- Add constraint ALTER TABLE Employees ADD CONSTRAINT fk_dept FOREIGN KEY (DepartmentID) REFERENCES Departments(DeptID);
DROP TABLE Employees;
SHOW TABLES;
DESCRIBE Employees; -- OR DESC Employees;
-- Insert single record INSERT INTO Employees (FirstName, LastName, Email, HireDate, Salary, DepartmentID) VALUES ('John', 'Doe', 'john.doe@email.com', '2023εΉ΄01ζ15ζ₯', 55000.00, 1); -- Insert multiple records INSERT INTO Employees (FirstName, LastName, Email, HireDate, Salary, DepartmentID) VALUES ('Jane', 'Smith', 'jane.smith@email.com', '2023εΉ΄02ζ01ζ₯', 60000.00, 2), ('Mike', 'Johnson', 'mike.johnson@email.com', '2023εΉ΄03ζ10ζ₯', 52000.00, 1); -- Insert from another table INSERT INTO EmployeeBackup SELECT * FROM Employees WHERE DepartmentID = 1;
-- Update single record UPDATE Employees SET Salary = 58000.00 WHERE EmployeeID = 1; -- Update multiple records UPDATE Employees SET Salary = Salary * 1.05 WHERE DepartmentID = 1; -- Update with JOIN UPDATE Employees e JOIN Departments d ON e.DepartmentID = d.DeptID SET e.Salary = e.Salary * 1.10 WHERE d.DepartmentName = 'Engineering';
-- Delete specific records DELETE FROM Employees WHERE EmployeeID = 1; -- Delete with condition DELETE FROM Employees WHERE HireDate < '2020εΉ΄01ζ01ζ₯'; -- Delete all records (but keep table structure) DELETE FROM Employees;
-- Select all columns SELECT * FROM Employees; -- Select specific columns SELECT FirstName, LastName, Salary FROM Employees; -- Select with alias SELECT FirstName AS 'First Name', LastName AS 'Last Name' FROM Employees;
-- Comparison operators SELECT * FROM Employees WHERE Salary > 50000; SELECT * FROM Employees WHERE DepartmentID = 1; SELECT * FROM Employees WHERE HireDate >= '2023εΉ΄01ζ01ζ₯'; -- Logical operators SELECT * FROM Employees WHERE Salary > 50000 AND DepartmentID = 1; SELECT * FROM Employees WHERE DepartmentID = 1 OR DepartmentID = 2; SELECT * FROM Employees WHERE NOT DepartmentID = 3; -- LIKE operator SELECT * FROM Employees WHERE FirstName LIKE 'J%'; -- Starts with 'J' SELECT * FROM Employees WHERE Email LIKE '%@gmail.com'; -- Ends with '@gmail.com' SELECT * FROM Employees WHERE FirstName LIKE 'J_hn'; -- 'J' + any char + 'hn' -- IN operator SELECT * FROM Employees WHERE DepartmentID IN (1, 2, 3); -- BETWEEN operator SELECT * FROM Employees WHERE Salary BETWEEN 50000 AND 70000; -- IS NULL / IS NOT NULL SELECT * FROM Employees WHERE Email IS NULL; SELECT * FROM Employees WHERE Email IS NOT NULL;
-- Ascending order (default) SELECT * FROM Employees ORDER BY LastName; -- Descending order SELECT * FROM Employees ORDER BY Salary DESC; -- Multiple columns SELECT * FROM Employees ORDER BY DepartmentID, Salary DESC;
-- Limit results SELECT * FROM Employees LIMIT 10; -- Pagination SELECT * FROM Employees LIMIT 10 OFFSET 20; -- Skip first 20, get next 10 -- TOP (SQL Server) SELECT TOP 10 * FROM Employees;
-- Remove duplicates SELECT DISTINCT DepartmentID FROM Employees; -- Distinct on multiple columns SELECT DISTINCT DepartmentID, Salary FROM Employees;
-- Employees table CREATE TABLE Employees ( EmployeeID INT PRIMARY KEY, FirstName VARCHAR(50), LastName VARCHAR(50), DepartmentID INT, Salary DECIMAL(10,2) ); -- Departments table CREATE TABLE Departments ( DeptID INT PRIMARY KEY, DepartmentName VARCHAR(50), Location VARCHAR(50) );
-- Returns only matching records from both tables SELECT e.FirstName, e.LastName, d.DepartmentName FROM Employees e INNER JOIN Departments d ON e.DepartmentID = d.DeptID;
-- Returns all records from left table and matching records from right table SELECT e.FirstName, e.LastName, d.DepartmentName FROM Employees e LEFT JOIN Departments d ON e.DepartmentID = d.DeptID;
-- Returns all records from right table and matching records from left table SELECT e.FirstName, e.LastName, d.DepartmentName FROM Employees e RIGHT JOIN Departments d ON e.DepartmentID = d.DeptID;
-- Returns all records from both tables SELECT e.FirstName, e.LastName, d.DepartmentName FROM Employees e FULL OUTER JOIN Departments d ON e.DepartmentID = d.DeptID;
-- Cartesian product of both tables SELECT e.FirstName, d.DepartmentName FROM Employees e CROSS JOIN Departments d;
-- Join table with itself SELECT e1.FirstName AS Employee, e2.FirstName AS Manager FROM Employees e1 LEFT JOIN Employees e2 ON e1.ManagerID = e2.EmployeeID;
-- COUNT SELECT COUNT(*) FROM Employees; -- Count all rows SELECT COUNT(Email) FROM Employees; -- Count non-null emails SELECT COUNT(DISTINCT DepartmentID) FROM Employees; -- Count unique departments -- SUM SELECT SUM(Salary) FROM Employees; -- Total salary SELECT SUM(Salary) FROM Employees WHERE DepartmentID = 1; -- AVG SELECT AVG(Salary) FROM Employees; -- Average salary SELECT AVG(Salary) AS AvgSalary FROM Employees; -- MIN and MAX SELECT MIN(Salary) AS MinSalary FROM Employees; SELECT MAX(Salary) AS MaxSalary FROM Employees; SELECT MIN(HireDate), MAX(HireDate) FROM Employees;
-- Group by single column SELECT DepartmentID, COUNT(*) AS EmployeeCount FROM Employees GROUP BY DepartmentID; -- Group by multiple columns SELECT DepartmentID, YEAR(HireDate) AS HireYear, COUNT(*) AS Count FROM Employees GROUP BY DepartmentID, YEAR(HireDate); -- With aggregate functions SELECT DepartmentID, COUNT(*) AS EmployeeCount, AVG(Salary) AS AvgSalary, SUM(Salary) AS TotalSalary FROM Employees GROUP BY DepartmentID;
-- Filter groups (use HAVING instead of WHERE with aggregates) SELECT DepartmentID, COUNT(*) AS EmployeeCount FROM Employees GROUP BY DepartmentID HAVING COUNT(*) > 5; -- Multiple conditions in HAVING SELECT DepartmentID, AVG(Salary) AS AvgSalary FROM Employees GROUP BY DepartmentID HAVING AVG(Salary) > 50000 AND COUNT(*) > 3;
-- LENGTH / LEN SELECT FirstName, LENGTH(FirstName) AS NameLength FROM Employees; -- UPPER / LOWER SELECT UPPER(FirstName), LOWER(LastName) FROM Employees; -- SUBSTRING / SUBSTR SELECT SUBSTRING(FirstName, 1, 3) AS FirstThreeChars FROM Employees; -- CONCAT SELECT CONCAT(FirstName, ' ', LastName) AS FullName FROM Employees; -- TRIM SELECT TRIM(FirstName) FROM Employees; -- Remove leading/trailing spaces SELECT LTRIM(FirstName) FROM Employees; -- Remove leading spaces SELECT RTRIM(FirstName) FROM Employees; -- Remove trailing spaces -- REPLACE SELECT REPLACE(Email, '@gmail.com', '@company.com') FROM Employees; -- LEFT / RIGHT SELECT LEFT(FirstName, 2) AS FirstTwo FROM Employees; -- First 2 characters SELECT RIGHT(FirstName, 2) AS LastTwo FROM Employees; -- Last 2 characters -- CHARINDEX / INSTR (find position of substring) SELECT CHARINDEX('@', Email) AS AtPosition FROM Employees;
-- Extract domain from email SELECT Email, SUBSTRING(Email, CHARINDEX('@', Email) + 1, LEN(Email)) AS Domain FROM Employees; -- Format names properly SELECT CONCAT(UPPER(LEFT(FirstName, 1)), LOWER(SUBSTRING(FirstName, 2, LEN(FirstName)))) AS FormattedName FROM Employees; -- Check if email is valid (contains @) SELECT FirstName, Email, CASE WHEN CHARINDEX('@', Email) > 0 THEN 'Valid' ELSE 'Invalid' END AS EmailStatus FROM Employees;
-- Current date and time SELECT NOW(); -- MySQL SELECT GETDATE(); -- SQL Server SELECT CURRENT_TIMESTAMP; -- Standard SQL -- Current date only SELECT CURDATE(); -- MySQL SELECT CAST(GETDATE() AS DATE); -- SQL Server -- Current time only SELECT CURTIME(); -- MySQL SELECT CAST(GETDATE() AS TIME); -- SQL Server
-- Extract parts of date SELECT HireDate, YEAR(HireDate) AS HireYear, MONTH(HireDate) AS HireMonth, DAY(HireDate) AS HireDay, DAYNAME(HireDate) AS HireDayName, -- MySQL MONTHNAME(HireDate) AS HireMonthName -- MySQL FROM Employees; -- SQL Server equivalents SELECT HireDate, YEAR(HireDate) AS HireYear, MONTH(HireDate) AS HireMonth, DAY(HireDate) AS HireDay, DATENAME(WEEKDAY, HireDate) AS HireDayName, DATENAME(MONTH, HireDate) AS HireMonthName FROM Employees;
-- Add/subtract dates (MySQL) SELECT HireDate, DATE_ADD(HireDate, INTERVAL 1 YEAR) AS OneYearLater, DATE_SUB(HireDate, INTERVAL 30 DAY) AS ThirtyDaysEarlier FROM Employees; -- SQL Server equivalents SELECT HireDate, DATEADD(YEAR, 1, HireDate) AS OneYearLater, DATEADD(DAY, -30, HireDate) AS ThirtyDaysEarlier FROM Employees; -- Calculate age or tenure SELECT FirstName, HireDate, DATEDIFF(YEAR, HireDate, CURDATE()) AS YearsOfService -- MySQL FROM Employees; -- SQL Server SELECT FirstName, HireDate, DATEDIFF(YEAR, HireDate, GETDATE()) AS YearsOfService FROM Employees;
-- Format dates (MySQL) SELECT HireDate, DATE_FORMAT(HireDate, '%Y-%m-%d') AS ISOFormat, DATE_FORMAT(HireDate, '%M %d, %Y') AS USFormat FROM Employees; -- SQL Server SELECT HireDate, FORMAT(HireDate, 'yyyy-MM-dd') AS ISOFormat, FORMAT(HireDate, 'MMMM dd, yyyy') AS USFormat FROM Employees;
-- Absolute value SELECT ABS(-15); -- Returns 15 -- Rounding SELECT ROUND(123.456, 2); -- Returns 123.46 SELECT CEIL(123.45); -- Returns 124 (round up) SELECT FLOOR(123.95); -- Returns 123 (round down) -- Power and square root SELECT POWER(2, 3); -- Returns 8 (2^3) SELECT SQRT(16); -- Returns 4 -- Random number SELECT RAND(); -- Returns random number between 0 and 1 SELECT RAND() * 100; -- Random number between 0 and 100
-- Calculate percentage SELECT FirstName, Salary, ROUND((Salary / (SELECT MAX(Salary) FROM Employees)) * 100, 2) AS SalaryPercentage FROM Employees; -- Calculate tax (assuming 25% tax rate) SELECT FirstName, Salary, ROUND(Salary * 0.25, 2) AS Tax, ROUND(Salary * 0.75, 2) AS NetSalary FROM Employees; -- Salary ranges SELECT CASE WHEN Salary < 40000 THEN 'Low' WHEN Salary BETWEEN 40000 AND 70000 THEN 'Medium' ELSE 'High' END AS SalaryRange, COUNT(*) AS EmployeeCount FROM Employees GROUP BY CASE WHEN Salary < 40000 THEN 'Low' WHEN Salary BETWEEN 40000 AND 70000 THEN 'Medium' ELSE 'High' END;
-- Simple CASE SELECT FirstName, Salary, CASE WHEN Salary > 70000 THEN 'High' WHEN Salary > 50000 THEN 'Medium' ELSE 'Low' END AS SalaryCategory FROM Employees; -- CASE with multiple conditions SELECT FirstName, DepartmentID, Salary, CASE WHEN DepartmentID = 1 AND Salary > 60000 THEN 'Senior Developer' WHEN DepartmentID = 1 THEN 'Developer' WHEN DepartmentID = 2 AND Salary > 55000 THEN 'Senior Analyst' WHEN DepartmentID = 2 THEN 'Analyst' ELSE 'Other' END AS JobTitle FROM Employees;
-- IF function SELECT FirstName, Salary, IF(Salary > 50000, 'Above Average', 'Below Average') AS SalaryStatus FROM Employees; -- Nested IF SELECT FirstName, Salary, IF(Salary > 70000, 'High', IF(Salary > 50000, 'Medium', 'Low')) AS SalaryCategory FROM Employees;
-- Handle NULL values SELECT FirstName, COALESCE(Email, 'No email provided') AS EmailStatus FROM Employees; -- SQL Server ISNULL SELECT FirstName, ISNULL(Email, 'No email provided') AS EmailStatus FROM Employees; -- MySQL IFNULL SELECT FirstName, IFNULL(Email, 'No email provided') AS EmailStatus FROM Employees;
-- Single column primary key CREATE TABLE Departments ( DeptID INT PRIMARY KEY, DepartmentName VARCHAR(50) ); -- Composite primary key CREATE TABLE EmployeeProjects ( EmployeeID INT, ProjectID INT, AssignmentDate DATE, PRIMARY KEY (EmployeeID, ProjectID) ); -- Add primary key to existing table ALTER TABLE Employees ADD PRIMARY KEY (EmployeeID);
-- Foreign key constraint CREATE TABLE Employees ( EmployeeID INT PRIMARY KEY, FirstName VARCHAR(50), DepartmentID INT, FOREIGN KEY (DepartmentID) REFERENCES Departments(DeptID) ); -- Named foreign key constraint CREATE TABLE Employees ( EmployeeID INT PRIMARY KEY, FirstName VARCHAR(50), DepartmentID INT, CONSTRAINT fk_employee_department FOREIGN KEY (DepartmentID) REFERENCES Departments(DeptID) ); -- Add foreign key to existing table ALTER TABLE Employees ADD CONSTRAINT fk_employee_department FOREIGN KEY (DepartmentID) REFERENCES Departments(DeptID);
-- Single column unique CREATE TABLE Employees ( EmployeeID INT PRIMARY KEY, Email VARCHAR(100) UNIQUE, FirstName VARCHAR(50) ); -- Multiple column unique CREATE TABLE Employees ( EmployeeID INT PRIMARY KEY, FirstName VARCHAR(50), LastName VARCHAR(50), UNIQUE (FirstName, LastName) ); -- Add unique constraint ALTER TABLE Employees ADD UNIQUE (Email);
-- Check constraint CREATE TABLE Employees ( EmployeeID INT PRIMARY KEY, FirstName VARCHAR(50), Salary DECIMAL(10,2) CHECK (Salary > 0), Age INT CHECK (Age >= 18 AND Age <= 65) ); -- Named check constraint CREATE TABLE Employees ( EmployeeID INT PRIMARY KEY, FirstName VARCHAR(50), Salary DECIMAL(10,2), CONSTRAINT chk_salary CHECK (Salary > 0) );
CREATE TABLE Employees ( EmployeeID INT PRIMARY KEY, FirstName VARCHAR(50) NOT NULL, LastName VARCHAR(50) NOT NULL, Email VARCHAR(100) ); -- Add NOT NULL to existing column ALTER TABLE Employees MODIFY FirstName VARCHAR(50) NOT NULL;
CREATE TABLE Employees ( EmployeeID INT PRIMARY KEY, FirstName VARCHAR(50) NOT NULL, HireDate DATE DEFAULT CURRENT_DATE, Status VARCHAR(20) DEFAULT 'Active', Salary DECIMAL(10,2) DEFAULT 50000.00 ); -- Add default to existing column ALTER TABLE Employees ALTER COLUMN Status SET DEFAULT 'Active';
-- Single column index CREATE INDEX idx_lastname ON Employees(LastName); -- Multiple column index CREATE INDEX idx_name ON Employees(FirstName, LastName); -- Unique index CREATE UNIQUE INDEX idx_email ON Employees(Email); -- Partial index (with condition) CREATE INDEX idx_active_employees ON Employees(DepartmentID) WHERE Status = 'Active';
DROP INDEX idx_lastname ON Employees; -- MySQL DROP INDEX idx_lastname; -- SQL Server, PostgreSQL
-- MySQL SHOW INDEX FROM Employees; -- SQL Server SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID('Employees'); -- PostgreSQL SELECT * FROM pg_indexes WHERE tablename = 'employees';
-- Simple view CREATE VIEW EmployeeView AS SELECT EmployeeID, FirstName, LastName, DepartmentID FROM Employees WHERE Status = 'Active'; -- Complex view with joins CREATE VIEW EmployeeDepartmentView AS SELECT e.EmployeeID, e.FirstName, e.LastName, d.DepartmentName, d.Location FROM Employees e JOIN Departments d ON e.DepartmentID = d.DeptID WHERE e.Status = 'Active'; -- View with calculations CREATE VIEW SalarySummaryView AS SELECT DepartmentID, COUNT(*) AS EmployeeCount, AVG(Salary) AS AvgSalary, MIN(Salary) AS MinSalary, MAX(Salary) AS MaxSalary FROM Employees GROUP BY DepartmentID;
-- Query view like a table SELECT * FROM EmployeeView; SELECT * FROM EmployeeDepartmentView WHERE DepartmentName = 'Engineering';
CREATE OR REPLACE VIEW EmployeeView AS SELECT EmployeeID, FirstName, LastName, Email, DepartmentID FROM Employees WHERE Status = 'Active';
DROP VIEW EmployeeView;
-- Simple stored procedure (SQL Server) CREATE PROCEDURE GetEmployeesByDepartment @DepartmentID INT AS BEGIN SELECT * FROM Employees WHERE DepartmentID = @DepartmentID; END; -- Stored procedure with multiple parameters CREATE PROCEDURE GetEmployeeBySalaryRange @MinSalary DECIMAL(10,2), @MaxSalary DECIMAL(10,2) AS BEGIN SELECT FirstName, LastName, Salary, DepartmentID FROM Employees WHERE Salary BETWEEN @MinSalary AND @MaxSalary ORDER BY Salary DESC; END; -- MySQL stored procedure DELIMITER // CREATE PROCEDURE GetEmployeesByDepartment(IN dept_id INT) BEGIN SELECT * FROM Employees WHERE DepartmentID = dept_id; END // DELIMITER ;
-- SQL Server EXEC GetEmployeesByDepartment @DepartmentID = 1; EXEC GetEmployeeBySalaryRange @MinSalary = 50000, @MaxSalary = 80000; -- MySQL CALL GetEmployeesByDepartment(1);
-- SQL Server CREATE PROCEDURE GetEmployeeCount @DepartmentID INT, @EmployeeCount INT OUTPUT AS BEGIN SELECT @EmployeeCount = COUNT(*) FROM Employees WHERE DepartmentID = @DepartmentID; END; -- Execute with output DECLARE @Count INT; EXEC GetEmployeeCount @DepartmentID = 1, @EmployeeCount = @Count OUTPUT; SELECT @Count AS EmployeeCount;
-- AFTER INSERT trigger CREATE TRIGGER tr_employee_insert ON Employees AFTER INSERT AS BEGIN INSERT INTO EmployeeAudit (EmployeeID, Action, ActionDate) SELECT EmployeeID, 'INSERT', GETDATE() FROM INSERTED; END; -- BEFORE UPDATE trigger (MySQL) DELIMITER // CREATE TRIGGER tr_employee_update BEFORE UPDATE ON Employees FOR EACH ROW BEGIN INSERT INTO EmployeeAudit (EmployeeID, OldSalary, NewSalary, Action, ActionDate) VALUES (NEW.EmployeeID, OLD.Salary, NEW.Salary, 'UPDATE', NOW()); END // DELIMITER ; -- AFTER DELETE trigger CREATE TRIGGER tr_employee_delete ON Employees AFTER DELETE AS BEGIN INSERT INTO EmployeeAudit (EmployeeID, Action, ActionDate) SELECT EmployeeID, 'DELETE', GETDATE() FROM DELETED; END;
DROP TRIGGER tr_employee_insert;
-- Start transaction BEGIN TRANSACTION; -- SQL Server START TRANSACTION; -- MySQL BEGIN; -- PostgreSQL -- Example transaction BEGIN TRANSACTION; UPDATE Employees SET Salary = Salary * 1.05 WHERE DepartmentID = 1; INSERT INTO SalaryAudit (EmployeeID, OldSalary, NewSalary, ChangeDate) SELECT EmployeeID, Salary / 1.05, Salary, GETDATE() FROM Employees WHERE DepartmentID = 1; COMMIT TRANSACTION; -- Rollback transaction BEGIN TRANSACTION; UPDATE Employees SET Salary = 0; -- Dangerous operation -- Oops, let's undo this ROLLBACK TRANSACTION;
BEGIN TRANSACTION; UPDATE Employees SET Salary = Salary * 1.05; SAVE TRANSACTION sp1; -- Create savepoint DELETE FROM Employees WHERE Salary < 30000; -- Rollback to savepoint (keeps salary updates) ROLLBACK TRANSACTION sp1; COMMIT TRANSACTION;
-- Set isolation level SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
-- ROW_NUMBER SELECT FirstName, LastName, Salary, ROW_NUMBER() OVER (ORDER BY Salary DESC) AS SalaryRank FROM Employees; -- RANK and DENSE_RANK SELECT FirstName, LastName, Salary, RANK() OVER (ORDER BY Salary DESC) AS SalaryRank, DENSE_RANK() OVER (ORDER BY Salary DESC) AS SalaryDenseRank FROM Employees; -- PARTITION BY SELECT FirstName, LastName, DepartmentID, Salary, ROW_NUMBER() OVER (PARTITION BY DepartmentID ORDER BY Salary DESC) AS DeptRank, AVG(Salary) OVER (PARTITION BY DepartmentID) AS DeptAvgSalary FROM Employees; -- LAG and LEAD SELECT FirstName, LastName, HireDate, LAG(HireDate, 1) OVER (ORDER BY HireDate) AS PreviousHire, LEAD(HireDate, 1) OVER (ORDER BY HireDate) AS NextHire FROM Employees;
-- Simple CTE WITH DepartmentStats AS ( SELECT DepartmentID, COUNT(*) AS EmployeeCount, AVG(Salary) AS AvgSalary FROM Employees GROUP BY DepartmentID ) SELECT d.DepartmentName, ds.EmployeeCount, ds.AvgSalary FROM DepartmentStats ds JOIN Departments d ON ds.DepartmentID = d.DeptID; -- Recursive CTE (for hierarchical data) WITH EmployeeHierarchy AS ( -- Anchor: Top-level managers SELECT EmployeeID, FirstName, LastName, ManagerID, 1 AS Level FROM Employees WHERE ManagerID IS NULL UNION ALL -- Recursive: Employees with managers SELECT e.EmployeeID, e.FirstName, e.LastName, e.ManagerID, eh.Level + 1 FROM Employees e JOIN EmployeeHierarchy eh ON e.ManagerID = eh.EmployeeID ) SELECT * FROM EmployeeHierarchy ORDER BY Level, LastName;
-- Scalar subquery SELECT FirstName, LastName, Salary, (SELECT AVG(Salary) FROM Employees) AS AvgSalary FROM Employees; -- Correlated subquery SELECT FirstName, LastName, Salary, DepartmentID FROM Employees e1 WHERE Salary > (SELECT AVG(Salary) FROM Employees e2 WHERE e2.DepartmentID = e1.DepartmentID); -- EXISTS SELECT FirstName, LastName FROM Employees e WHERE EXISTS (SELECT 1 FROM Departments d WHERE d.DeptID = e.DepartmentID AND d.DepartmentName = 'Engineering'); -- IN with subquery SELECT FirstName, LastName FROM Employees WHERE DepartmentID IN (SELECT DeptID FROM Departments WHERE Location = 'New York');
-- PIVOT SELECT * FROM ( SELECT DepartmentID, YEAR(HireDate) AS HireYear FROM Employees ) AS SourceTable PIVOT ( COUNT(DepartmentID) FOR HireYear IN ([2021], [2022], [2023]) ) AS PivotTable; -- UNPIVOT SELECT DepartmentID, HireYear, EmployeeCount FROM ( SELECT DepartmentID, [2021], [2022], [2023] FROM YearlyHires ) AS SourceTable UNPIVOT ( EmployeeCount FOR HireYear IN ([2021], [2022], [2023]) ) AS UnpivotTable;
-
Use Indexes Effectively
-- Create indexes on frequently queried columns CREATE INDEX idx_department_salary ON Employees(DepartmentID, Salary);
-
Avoid SELECT *
-- Instead of SELECT * FROM Employees; -- Use SELECT FirstName, LastName, Salary FROM Employees;
-
Use WHERE to Filter Early
-- Filter before joining when possible SELECT e.FirstName, d.DepartmentName FROM (SELECT * FROM Employees WHERE Salary > 50000) e JOIN Departments d ON e.DepartmentID = d.DeptID;
-
Use EXISTS Instead of IN for Large Datasets
-- More efficient for large datasets SELECT FirstName, LastName FROM Employees e WHERE EXISTS (SELECT 1 FROM Departments d WHERE d.DeptID = e.DepartmentID AND d.Location = 'New York');
-
Avoid Functions in WHERE Clause
-- Instead of SELECT * FROM Employees WHERE YEAR(HireDate) = 2023; -- Use SELECT * FROM Employees WHERE HireDate >= '2023εΉ΄01ζ01ζ₯' AND HireDate < '2024εΉ΄01ζ01ζ₯';
-- Using ROW_NUMBER() WITH RankedSalaries AS ( SELECT Salary, ROW_NUMBER() OVER (ORDER BY Salary DESC) AS rn FROM Employees ) SELECT Salary FROM RankedSalaries WHERE rn = 2; -- 2nd highest -- Using LIMIT/OFFSET (MySQL) SELECT DISTINCT Salary FROM Employees ORDER BY Salary DESC LIMIT 1 OFFSET 1; -- 2nd highest
-- Find employees with same name SELECT FirstName, LastName, COUNT(*) FROM Employees GROUP BY FirstName, LastName HAVING COUNT(*) > 1; -- Find all duplicate records SELECT * FROM Employees e1 WHERE EXISTS (SELECT 1 FROM Employees e2 WHERE e1.FirstName = e2.FirstName AND e1.LastName = e2.LastName AND e1.EmployeeID != e2.EmployeeID);
SELECT e.FirstName, e.LastName FROM Employees e LEFT JOIN Departments d ON e.DepartmentID = d.DeptID WHERE d.DeptID IS NULL;
SELECT EmployeeID, Salary, SUM(Salary) OVER (ORDER BY EmployeeID) AS RunningTotal FROM Employees ORDER BY EmployeeID;
SELECT TOP 1 d.DepartmentName, AVG(e.Salary) AS AvgSalary FROM Employees e JOIN Departments d ON e.DepartmentID = d.DeptID GROUP BY d.DepartmentName ORDER BY AVG(e.Salary) DESC;
This SQL cheat sheet covers the fundamental to advanced concepts you need to master SQL. Practice these queries with sample data to improve your understanding and performance in interviews or real-world applications.
- Always understand the query execution order
- Use appropriate indexes for performance
- Normalize your database design
- Use transactions for data integrity
- Practice window functions for advanced analytics
- Master joins for relational data
- SQL Standards Documentation
- MySQL Documentation
- PostgreSQL Documentation
- SQL Server Documentation
- SQLite Documentation
Found an error or want to suggest improvements? We welcome contributions from the community!
- Check existing content for accuracy
- Suggest additions for missing scenarios
- Report issues with examples that don't work
- Share best practices from your experience
- Visit the repository: Go to https://github.com/Vipul1432/SQL_CheatSheet
- Click Fork: Click the "Fork" button in the top-right corner
- Choose destination: Select your GitHub account to create a fork
# Clone your forked repository git clone https://github.com/YOUR_USERNAME/SQL_CheatSheet.git # Navigate to the project directory cd SQL_CheatSheet # Add upstream remote to sync with original repo git remote add upstream https://github.com/Vipul1432/SQL_CheatSheet.git
# Create and switch to a new branch for your feature git checkout -b feature/your-feature-name # Examples: git checkout -b feature/add-nosql-examples git checkout -b feature/fix-typos git checkout -b feature/add-postgresql-functions
- Edit files using your preferred editor
- Add new content following the existing format
- Test examples to ensure they work correctly
- Follow naming conventions used in the project
# Stage your changes git add . # Commit with a descriptive message git commit -m "Add PostgreSQL-specific functions to date operations - Include PostgreSQL date/time functions - Add examples with expected outputs - Update table of contents - Fix formatting issues in mathematical functions"
# Fetch latest changes from original repository git fetch upstream # Merge latest changes into your branch git merge upstream/main
# Push your feature branch to your fork
git push origin feature/your-feature-name
- Go to GitHub: Visit your forked repository on GitHub
- Click "Compare & pull request": GitHub usually shows this button automatically
- Fill out the PR template:
- Title: Clear, descriptive title
- Description: Explain what you changed and why
- Related issues: Reference any related issues with
#issue-number
- Submit the pull request
- Bug fixes and typo corrections
- New SQL examples with clear explanations
- Database-specific functions (MySQL, PostgreSQL, SQL Server, Oracle)
- Performance optimization tips and examples
- Documentation improvements and clarifications
- Additional interview questions with solutions
- Incomplete examples without proper explanation
- Untested code that doesn't work
- Formatting inconsistencies that break the document structure
- Duplicate content already covered in the cheat sheet
- Use consistent formatting with existing content
- Include practical examples with expected outputs
- Add table entries in the same format as existing tables
- Test all SQL queries before submitting
- Use clear, concise explanations
- Follow markdown best practices
- Use descriptive titles: "Fix incorrect DATEADD syntax in SQL Server section"
- Provide context: Which section, which example, what's wrong
- Include expected behavior: What should happen instead
- Add screenshots if applicable for formatting issues
**Section**: [e.g., Date Functions, JOIN Operations] **Database**: [e.g., SQL Server, MySQL, PostgreSQL] **Issue Type**: [Bug, Enhancement, Question] **Description**: Clear description of the issue or suggestion **Current Behavior**: What currently happens **Expected Behavior**: What should happen instead **Additional Context**: Any other relevant information
- Git installed on your system
- Text editor or IDE (VS Code, Sublime Text, etc.)
- Basic markdown knowledge
- SQL testing environment (optional but recommended)
- Preview markdown: Use a markdown viewer to check formatting
- Test SQL queries: Run examples in your preferred database system
- Check links: Ensure all internal links work correctly
- Validate syntax: Check for markdown syntax errors
All contributors will be acknowledged in:
- Contributors section (coming soon)
- Git commit history
- Release notes for significant contributions
- Issues: Use GitHub Issues for bug reports and feature requests
- Discussions: Use GitHub Discussions for questions and general discussion
- Email: Contact repository owner for urgent matters
Happy Querying! π