CREATE TABLE Departments (
DepartmentID INT PRIMARY KEY,
Name VARCHAR(50)
);
CREATE TABLE Employees (
EmployeeID INT PRIMARY KEY,
DepartmentID INT,
FOREIGN KEY (DepartmentID) REFERENCES Departments(DepartmentID)
);
-- Valid insert
INSERT INTO Departments VALUES (1, 'HR');
INSERT INTO Employees VALUES (1, 1);
-- Invalid insert (violates referential integrity)
-- INSERT INTO Employees VALUES (2, 999); -- Error
CREATE TABLE Departments (
DepartmentID INT PRIMARY KEY,
Name VARCHAR(50)
);
CREATE TABLE Employees (
EmployeeID INT PRIMARY KEY,
DepartmentID INT,
FOREIGN KEY (DepartmentID) REFERENCES Departments(DepartmentID)
);
-- Valid insert
INSERT INTO Departments VALUES (1, 'HR');
INSERT INTO Employees VALUES (1, 1);
-- Invalid insert (violates referential integrity)
-- INSERT INTO Employees VALUES (2, 999); -- Error
-- 1NF: Remove repeating groups
CREATE TABLE Orders (
OrderID INT PRIMARY KEY,
CustomerID INT,
Product VARCHAR(50) -- No arrays
);
-- 2NF: Remove partial dependency
CREATE TABLE OrderDetails (
OrderID INT,
ProductID INT,
Quantity INT,
PRIMARY KEY (OrderID, ProductID)
);
-- 3NF: Remove transitive dependency
CREATE TABLE Customers (
CustomerID INT PRIMARY KEY,
CustomerName VARCHAR(50),
City VARCHAR(50) -- Moved from Orders
);
-- 1NF: Remove repeating groups
CREATE TABLE Orders (
OrderID INT PRIMARY KEY,
CustomerID INT,
Product VARCHAR(50) -- No arrays
);
-- 2NF: Remove partial dependency
CREATE TABLE OrderDetails (
OrderID INT,
ProductID INT,
Quantity INT,
PRIMARY KEY (OrderID, ProductID)
);
-- 3NF: Remove transitive dependency
CREATE TABLE Customers (
CustomerID INT PRIMARY KEY,
CustomerName VARCHAR(50),
City VARCHAR(50) -- Moved from Orders
);
-- INNER JOIN
SELECT e.EmployeeID, e.Name, d.DepartmentName
FROM Employees e
INNER JOIN Departments d ON e.DepartmentID = d.DepartmentID;
-- LEFT JOIN
SELECT e.EmployeeID, e.Name, d.DepartmentName
FROM Employees e
LEFT JOIN Departments d ON e.DepartmentID = d.DepartmentID;
-- INNER JOIN
SELECT e.EmployeeID, e.Name, d.DepartmentName
FROM Employees e
INNER JOIN Departments d ON e.DepartmentID = d.DepartmentID;
-- LEFT JOIN
SELECT e.EmployeeID, e.Name, d.DepartmentName
FROM Employees e
LEFT JOIN Departments d ON e.DepartmentID = d.DepartmentID;
-- DDL: Create table
CREATE TABLE Employees (EmployeeID INT PRIMARY KEY, Name VARCHAR(50));
-- DML: Insert data
INSERT INTO Employees VALUES (1, 'John');
-- DCL: Grant permission
GRANT SELECT ON Employees TO User1;
-- TCL: Commit transaction
BEGIN TRANSACTION;
INSERT INTO Employees VALUES (2, 'Jane');
COMMIT;
-- DDL: Create table
CREATE TABLE Employees (EmployeeID INT PRIMARY KEY, Name VARCHAR(50));
-- DML: Insert data
INSERT INTO Employees VALUES (1, 'John');
-- DCL: Grant permission
GRANT SELECT ON Employees TO 'User1'@'localhost';
-- TCL: Commit transaction
START TRANSACTION;
INSERT INTO Employees VALUES (2, 'Jane');
COMMIT;
-- WHERE: Filter individual rows
SELECT EmployeeID, Salary
FROM Employees
WHERE Salary > 50000;
-- HAVING: Filter groups
SELECT Department, AVG(Salary) AS AvgSalary
FROM Employees
GROUP BY Department
HAVING AVG(Salary) > 60000;
-- WHERE: Filter individual rows
SELECT EmployeeID, Salary
FROM Employees
WHERE Salary > 50000;
-- HAVING: Filter groups
SELECT Department, AVG(Salary) AS AvgSalary
FROM Employees
GROUP BY Department
HAVING AVG(Salary) > 60000;
-- Primary Key
CREATE TABLE Employees (
EmployeeID INT PRIMARY KEY,
Email VARCHAR(100) UNIQUE
);
-- Unique Key allows NULL
INSERT INTO Employees (EmployeeID, Email) VALUES (1, NULL);
-- Primary Key
CREATE TABLE Employees (
EmployeeID INT PRIMARY KEY,
Email VARCHAR(100) UNIQUE
);
-- Unique Key allows NULL
INSERT INTO Employees (EmployeeID, Email) VALUES (1, NULL);
-- Normalized
CREATE TABLE Customers (CustomerID INT PRIMARY KEY, Name VARCHAR(50));
CREATE TABLE Orders (OrderID INT PRIMARY KEY, CustomerID INT, OrderDate DATE);
-- Denormalized
CREATE TABLE DenormOrders (
OrderID INT PRIMARY KEY,
CustomerID INT,
CustomerName VARCHAR(50), -- Redundant
OrderDate DATE
);
-- Normalized
CREATE TABLE Customers (CustomerID INT PRIMARY KEY, Name VARCHAR(50));
CREATE TABLE Orders (OrderID INT PRIMARY KEY, CustomerID INT, OrderDate DATE);
-- Denormalized
CREATE TABLE DenormOrders (
OrderID INT PRIMARY KEY,
CustomerID INT,
CustomerName VARCHAR(50), -- Redundant
OrderDate DATE
);
SELECT
COUNT(*) AS TotalEmployees,
SUM(Salary) AS TotalSalary,
AVG(Salary) AS AvgSalary,
MAX(Salary) AS MaxSalary,
MIN(Salary) AS MinSalary
FROM Employees;
SELECT
COUNT(*) AS TotalEmployees,
SUM(Salary) AS TotalSalary,
AVG(Salary) AS AvgSalary,
MAX(Salary) AS MaxSalary,
MIN(Salary) AS MinSalary
FROM Employees;
-- Single-Row Subquery
SELECT Name
FROM Employees
WHERE Salary = (SELECT MAX(Salary) FROM Employees);
-- Multi-Row Subquery
SELECT Name
FROM Employees
WHERE DepartmentID IN (SELECT DepartmentID FROM Departments WHERE Location = 'NY');
-- Correlated Subquery
SELECT Name
FROM Employees e
WHERE EXISTS (SELECT 1 FROM Orders o WHERE o.EmployeeID = e.EmployeeID);
-- Single-Row Subquery
SELECT Name
FROM Employees
WHERE Salary = (SELECT MAX(Salary) FROM Employees);
-- Multi-Row Subquery
SELECT Name
FROM Employees
WHERE DepartmentID IN (SELECT DepartmentID FROM Departments WHERE Location = 'NY');
-- Correlated Subquery
SELECT Name
FROM Employees e
WHERE EXISTS (SELECT 1 FROM Orders o WHERE o.EmployeeID = e.EmployeeID);
-- DELETE: Remove specific rows
DELETE FROM Employees WHERE Salary < 30000;
-- TRUNCATE: Remove all rows
TRUNCATE TABLE Employees;
-- DROP: Remove table
DROP TABLE Employees;
-- DELETE: Remove specific rows
DELETE FROM Employees WHERE Salary < 30000;
-- TRUNCATE: Remove all rows
TRUNCATE TABLE Employees;
-- DROP: Remove table
DROP TABLE Employees;
SELECT Department, COUNT(*) AS EmployeeCount, AVG(Salary) AS AvgSalary
FROM Employees
GROUP BY Department
HAVING COUNT(*) > 5;
SELECT Department, COUNT(*) AS EmployeeCount, AVG(Salary) AS AvgSalary
FROM Employees
GROUP BY Department
HAVING COUNT(*) > 5;
-- Create Table
CREATE TABLE Employees (EmployeeID INT, Name VARCHAR(50), Salary INT);
-- Create View
CREATE VIEW HighEarners AS
SELECT EmployeeID, Name, Salary
FROM Employees
WHERE Salary > 50000;
-- Query View
SELECT * FROM HighEarners;
-- Create Table
CREATE TABLE Employees (EmployeeID INT, Name VARCHAR(50), Salary INT);
-- Create View
CREATE VIEW HighEarners AS
SELECT EmployeeID, Name, Salary
FROM Employees
WHERE Salary > 50000;
-- Query View
SELECT * FROM HighEarners;
-- Create Table
CREATE TABLE Employees (EmployeeID INT, Name VARCHAR(50));
-- Create Index
CREATE NONCLUSTERED INDEX IX_Employees_Name ON Employees(Name);
-- Query using Index
SELECT Name FROM Employees WHERE Name = 'John';
-- Create Table
CREATE TABLE Employees (EmployeeID INT, Name VARCHAR(50));
-- Create Index
CREATE INDEX IX_Employees_Name ON Employees(Name);
-- Query using Index
SELECT Name FROM Employees WHERE Name = 'John';
CREATE TABLE Test (
Fixed CHAR(5),
Variable VARCHAR(5)
);
INSERT INTO Test VALUES ('ABC', 'ABC');
-- CHAR: 'ABC ' (padded with spaces)
-- VARCHAR: 'ABC' (no padding)
SELECT DATALENGTH(Fixed), DATALENGTH(Variable) FROM Test; -- 5, 3
CREATE TABLE Test (
Fixed CHAR(5),
Variable VARCHAR(5)
);
INSERT INTO Test VALUES ('ABC', 'ABC');
-- CHAR: 'ABC ' (padded with spaces)
-- VARCHAR: 'ABC' (no padding)
SELECT LENGTH(Fixed), LENGTH(Variable) FROM Test; -- 5, 3
SELECT Name
FROM Employees
WHERE Name LIKE 'A%'; -- Names starting with A
SELECT Name
FROM Employees
WHERE Name LIKE 'J_n'; -- e.g., Jon, Jan
SELECT Name
FROM Employees
WHERE Name LIKE 'A%'; -- Names starting with A
SELECT Name
FROM Employees
WHERE Name LIKE 'J_n'; -- e.g., Jon, Jan
-- Top 5 employees by salary
SELECT TOP 5 EmployeeID, Name, Salary
FROM Employees
ORDER BY Salary DESC;
-- Top 5 employees by salary
SELECT EmployeeID, Name, Salary
FROM Employees
ORDER BY Salary DESC
LIMIT 5;
CREATE TABLE Employees (
EmployeeID INT PRIMARY KEY,
Name VARCHAR(50) NOT NULL,
Email VARCHAR(100) UNIQUE,
Age INT CHECK (Age >= 18),
DepartmentID INT,
Salary INT DEFAULT 30000,
FOREIGN KEY (DepartmentID) REFERENCES Departments(DepartmentID)
);
CREATE TABLE Employees (
EmployeeID INT PRIMARY KEY,
Name VARCHAR(50) NOT NULL,
Email VARCHAR(100) UNIQUE,
Age INT CHECK (Age >= 18),
DepartmentID INT,
Salary INT DEFAULT 30000,
FOREIGN KEY (DepartmentID) REFERENCES Departments(DepartmentID)
);
-- Find duplicate emails
SELECT Email, COUNT(*) AS Count
FROM Employees
GROUP BY Email
HAVING COUNT(*) > 1;
-- Get full duplicate rows
SELECT EmployeeID, Email
FROM Employees
WHERE Email IN (
SELECT Email
FROM Employees
GROUP BY Email
HAVING COUNT(*) > 1
)
ORDER BY Email;
-- Find duplicate emails
SELECT Email, COUNT(*) AS Count
FROM Employees
GROUP BY Email
HAVING COUNT(*) > 1;
-- Get full duplicate rows
SELECT EmployeeID, Email
FROM Employees
WHERE Email IN (
SELECT Email
FROM Employees
GROUP BY Email
HAVING COUNT(*) > 1
)
ORDER BY Email;
-- Unique departments
SELECT DISTINCT Department
FROM Employees;
-- Unique employee-department combinations
SELECT DISTINCT EmployeeID, Department
FROM Employees;
-- Unique departments
SELECT DISTINCT Department
FROM Employees;
-- Unique employee-department combinations
SELECT DISTINCT EmployeeID, Department
FROM Employees;
-- Employees and their managers
SELECT e1.Name AS Employee, e2.Name AS Manager
FROM Employees e1
LEFT JOIN Employees e2 ON e1.ManagerID = e2.EmployeeID;
-- Employees and their managers
SELECT e1.Name AS Employee, e2.Name AS Manager
FROM Employees e1
LEFT JOIN Employees e2 ON e1.ManagerID = e2.EmployeeID;
-- UNION: Remove duplicates
SELECT Name FROM Employees
UNION
SELECT Name FROM Contractors;
-- UNION ALL: Keep duplicates
SELECT Name FROM Employees
UNION ALL
SELECT Name FROM Contractors;
-- UNION: Remove duplicates
SELECT Name FROM Employees
UNION
SELECT Name FROM Contractors;
-- UNION ALL: Keep duplicates
SELECT Name FROM Employees
UNION ALL
SELECT Name FROM Contractors;
-- Stored Procedure
CREATE PROCEDURE GetHighEarners
@MinSalary INT
AS
BEGIN
SELECT EmployeeID, Name, Salary
FROM Employees
WHERE Salary > @MinSalary;
END;
EXEC GetHighEarners @MinSalary = 50000;
-- Function
CREATE FUNCTION GetAverageSalary (@DepartmentID INT)
RETURNS DECIMAL(10,2)
AS
BEGIN
RETURN (SELECT AVG(Salary) FROM Employees WHERE DepartmentID = @DepartmentID);
END;
SELECT dbo.GetAverageSalary(1);
-- Stored Procedure
DELIMITER //
CREATE PROCEDURE GetHighEarners(IN MinSalary INT)
BEGIN
SELECT EmployeeID, Name, Salary
FROM Employees
WHERE Salary > MinSalary;
END //
DELIMITER ;
CALL GetHighEarners(50000);
-- Function
CREATE FUNCTION GetAverageSalary(DepartmentID INT)
RETURNS DECIMAL(10,2)
DETERMINISTIC
BEGIN
DECLARE avgSalary DECIMAL(10,2);
SELECT AVG(Salary) INTO avgSalary FROM Employees WHERE DepartmentID = DepartmentID;
RETURN avgSalary;
END;
SELECT GetAverageSalary(1);
-- Update salary for specific employee
UPDATE Employees
SET Salary = 60000
WHERE EmployeeID = 1;
-- Update multiple columns
UPDATE Employees
SET Salary = Salary + 5000, DepartmentID = 2
WHERE Name = 'John';
-- Update salary for specific employee
UPDATE Employees
SET Salary = 60000
WHERE EmployeeID = 1;
-- Update multiple columns
UPDATE Employees
SET Salary = Salary + 5000, DepartmentID = 2
WHERE Name = 'John';
BEGIN TRANSACTION;
BEGIN TRY
UPDATE Accounts
SET Balance = Balance - 100
WHERE AccountID = 1;
UPDATE Accounts
SET Balance = Balance + 100
WHERE AccountID = 2;
COMMIT;
END TRY
BEGIN CATCH
ROLLBACK;
SELECT ERROR_MESSAGE();
END CATCH;
START TRANSACTION;
UPDATE Accounts
SET Balance = Balance - 100
WHERE AccountID = 1;
UPDATE Accounts
SET Balance = Balance + 100
WHERE AccountID = 2;
COMMIT;
-- On error, manually rollback
-- ROLLBACK;
-- Find NULLs
SELECT Name
FROM Employees
WHERE Email IS NULL;
-- Replace NULL with default
SELECT Name, COALESCE(Email, 'No Email') AS Email
FROM Employees;
-- ISNULL (SQL Server specific)
SELECT Name, ISNULL(Email, 'No Email') AS Email
FROM Employees;
-- NULLIF
SELECT Name, NULLIF(Salary, 0) AS Salary
FROM Employees;
-- Find NULLs
SELECT Name
FROM Employees
WHERE Email IS NULL;
-- Replace NULL with default
SELECT Name, COALESCE(Email, 'No Email') AS Email
FROM Employees;
-- NULLIF
SELECT Name, NULLIF(Salary, 0) AS Salary
FROM Employees;