1 - SQL_DE_Feb25
1 - SQL_DE_Feb25
Introduction to SQL
6. ALTER Statement
8. Joins in SQL
9. Self-Join
11. Subqueries
Numeric Types
Numeric data types are used to store numbers. They can be divided into two main
categories: integers and floating-point numbers.
• INT: A standard integer type that can store whole numbers without decimal
points. Example: age INT;
• FLOAT: (approximate) Used for floating-point numbers that require decimal
precision. Example: price FLOAT(5, 2); (where 5 is the total number of digits,
and 2 is the number of digits after the decimal point).
• DECIMAL: (accurate)This type is used for fixed-point numbers and is often
utilized in financial applications to avoid rounding issues. Example: salary
DECIMAL(10, 2);
Character Types
Character data types are designed to store fixed-length or variable-length strings of
characters.
• CHAR: Fixed-length character strings. Example: gender CHAR(1); (stores 'M'
or 'F').
• VARCHAR: Variable-length character strings, which can store up to a
specified maximum length. Example: first_name VARCHAR(50);
String Types
String data types are similar to character types but are typically used for larger text
blocks.
• TEXT: A data type for large text strings, which can hold up to 65,535
characters. Example: description TEXT;
• CLOB: Character Large Object, used to store large amounts of character
data. Example: bio CLOB;
Binary Types
Binary data types are used to store binary data, such as images or files.
• BLOB: Binary Large Object, which can store up to 65,535 bytes of binary
data. Example: image BLOB;
• VARBINARY: Variable-length binary data. Example: file VARBINARY(255);
Each of these data types plays a pivotal role in ensuring that the data stored in a
database is accurate, efficient, and suited to the needs of applications. Properly
selecting data types can significantly impact the performance and storage efficiency
of a database system.
SQL Operators
SELECT Statement and WHERE Clause
The SELECT statement is one of the most fundamental commands in SQL, as it
allows users to retrieve data from one or more tables within a database. The basic
syntax of a SELECT statement is as follows:
SELECT column1, column2, ...
FROM table_name
WHERE condition;
In this syntax, column1, column2, etc., represent the specific columns of data that
you wish to retrieve, while table_name indicates the table from which the data is
being selected. The WHERE clause is optional but crucial for filtering records based
on specific criteria.
For example, consider a hypothetical sales database with a table named
sales_records. This table includes columns such as sale_id, customer_name,
product, quantity, and sale_date. If we want to retrieve all sales made for a specific
product, say "Laptop," the SQL query would look like this:
SELECT *
FROM sales_records
WHERE product = 'Laptop';
This query retrieves all columns for the records where the product column matches
"Laptop." The use of the asterisk (*) indicates that all columns should be returned.
The WHERE clause can also utilize various operators to refine the search further.
For instance, to find sales records where the quantity sold is greater than 10, the
query would be:
SELECT *
FROM sales_records
WHERE quantity > 10;
Moreover, the WHERE clause supports logical operators such as AND, OR, and
NOT for combining multiple conditions. If we want to retrieve records for sales that
occurred in the year 2023 and involved a quantity greater than 5, the SQL statement
would be:
SELECT *
FROM sales_records
WHERE sale_date >= '2023-01-01' AND quantity > 5;
These examples illustrate how the SELECT statement, combined with the WHERE
clause, provides flexible and powerful options for data retrieval, enabling users to
extract precisely the information they need from their databases.
INSERT, UPDATE, and DELETE Statements
In SQL, the ability to manipulate data is a core function that allows users to maintain
and update records within a database. The three primary operations for modifying
data in a SQL database are the INSERT, UPDATE, and DELETE statements. Each
of these operations serves a unique purpose, enabling users to add new records,
modify existing data, or remove records altogether. To illustrate these functions, we
will use a hypothetical sales table, which contains columns such as sale_id,
customer_name, product, quantity, and sale_date.
INSERT Statement
The INSERT statement is used to add new records to a table. For example, if we
want to add a new sale record for a customer named "Alice" who purchased 3 units
of "Smartphone", the SQL command would be:
INSERT INTO sales (customer_name, product, quantity, sale_date)
VALUES ('Alice', 'Smartphone', 3, '2023-10-01');
This command adds a new row to the sales table with the specified values.
UPDATE Statement
The UPDATE statement allows users to modify existing records in a table. For
instance, if we need to update the quantity of products sold by changing Alice's
purchase from 3 to 5 units, the SQL command would be:
UPDATE sales
SET quantity = 5
WHERE customer_name = 'Alice' AND product = 'Smartphone';
This command finds the record that matches the specified conditions and updates
the quantity field accordingly.
DELETE Statement
The DELETE statement is used to remove records from a table. If we want to delete
the sale record associated with Alice's purchase, the SQL command would be:
DELETE FROM sales
WHERE customer_name = 'Alice' AND product = 'Smartphone';
This command identifies the record that meets the specified conditions and removes
it from the sales table.
These three statements—INSERT, UPDATE, and DELETE—are essential for
effective database management, allowing users to maintain accurate and up-to-date
records in their SQL databases.
Notes:
Delete – removes specific rows
Truncate – removes all rows
Drop – removes entire from Db
Alter – add column, modify column, drop column
ALTER Statement
The ALTER TABLE statement is a crucial SQL command used for modifying the
structure of an existing table in a database. As data requirements evolve over time,
the ability to change table definitions is essential for maintaining database integrity
and functionality. This statement enables database administrators and developers to
add, modify, or drop columns, as well as to change data types and constraints
without the need to recreate the entire table.
There are several scenarios where using the ALTER TABLE statement becomes
necessary. For instance, a business may need to expand its data storage
capabilities by adding new fields to accommodate additional information. If a
company decides to collect phone numbers for customer records, it would use the
ALTER statement to add a new column named phone_number to the customers
table. An example of this command would be:
ALTER TABLE customers
ADD COLUMN phone_number VARCHAR(15);
In another scenario, a business might realize that a column's data type is insufficient
for the data it needs to store. For example, if the salary column in an employees
table currently uses an INT type but needs to store larger values, the administrator
could modify the column to a DECIMAL type as follows:
ALTER TABLE employees
MODIFY COLUMN salary DECIMAL(10, 2);
The ALTER TABLE statement is vital for ensuring that database schemas remain
aligned with changing business needs, providing flexibility to adapt to new
information requirements efficiently.
ORDER BY, GROUP BY, and HAVING Clauses
In SQL, the ORDER BY, GROUP BY, and HAVING clauses are essential for
organizing and analyzing data effectively. Each clause serves a distinct purpose,
allowing users to sort results, aggregate data, and filter aggregated results,
respectively.
ORDER BY Clause
The ORDER BY clause is used to sort the results of a query based on one or more
columns. By default, sorting is done in ascending order, but it can be specified as
descending using the DESC keyword. For instance, if we want to retrieve a list of
employees sorted by their hire date, the SQL query would look like this:
SELECT *
FROM employees
ORDER BY hire_date ASC;
In this example, the results will be displayed with the earliest hire dates first. If we
wanted to sort by salary in descending order, the query would be modified to:
SELECT *
FROM employees
ORDER BY salary DESC;
GROUP BY Clause
The GROUP BY clause is utilized to aggregate data based on one or more columns.
This clause is often used in conjunction with aggregate functions like COUNT(),
SUM(), AVG(), MIN(), and MAX(). For example, if we need to calculate the total
sales for each product in a sales table, we can use:
SELECT product, SUM(quantity) AS total_sales
FROM sales
GROUP BY product;
This query groups the records by the product column and calculates the total
quantity sold for each product.
HAVING Clause
The HAVING clause is used to filter records after aggregation has occurred, which is
not possible with the WHERE clause. For instance, if we want to find products that
have total sales greater than 100 units, we can extend the previous query with a
HAVING clause:
SELECT product, SUM(quantity) AS total_sales
FROM sales
GROUP BY product
HAVING SUM(quantity) > 100;
In this example, the HAVING clause filters the grouped results to only include
products with total sales exceeding 100 units. Together, these clauses enhance the
ability to analyze and interpret data effectively, enabling users to derive valuable
insights from their datasets.
Joins in SQL
JOIN operations in SQL are fundamental for combining rows from two or more tables
based on a related column. By leveraging JOINs, users can retrieve comprehensive
datasets that reflect the relationships among various entities. The most common
types of JOINs include INNER JOIN, LEFT JOIN, RIGHT JOIN, and FULL OUTER
JOIN, each serving distinct purposes.
INNER JOIN
An INNER JOIN returns only the rows that have matching values in both tables. For
example, consider two tables: employees and departments. The employees table
contains a department_id column that relates to the departments table’s id column.
To retrieve a list of employees along with their corresponding department names, the
SQL query would be:
SELECT employees.name, departments.name
FROM employees
INNER JOIN departments ON employees.department_id = departments.id;
This query returns only those employees who belong to a department, omitting any
employees without an associated department.
LEFT JOIN
A LEFT JOIN returns all the rows from the left table and the matched rows from the
right table. If there is no match, NULL values are returned for columns from the right
table. For instance, if we want to get a list of all employees and their departments,
including those without departments, we would use:
SELECT employees.name, departments.name
FROM employees
LEFT JOIN departments ON employees.department_id = departments.id;
This query will include all employees, displaying NULL for department names where
no match exists.
RIGHT JOIN
A RIGHT JOIN operates similarly to a LEFT JOIN, but it returns all the rows from the
right table and the matching rows from the left table. If there’s no match, NULL
values appear for columns from the left table. Using the previous example, if we
want all departments listed with their employees, even if some departments have no
employees, the query would be:
SELECT employees.name, departments.name
FROM employees
RIGHT JOIN departments ON employees.department_id = departments.id;
This query will show all departments, with NULL for employee names where no
match exists.
This query captures all employees and departments, filling in NULLs where
relationships do not exist.
Understanding these JOIN types is crucial for effective data retrieval and analysis in
relational databases, as they enable users to create nuanced queries that reflect
complex data relationships.
Self-Join
A self-join is a special type of join in SQL where a table is joined with itself. This
technique is useful for querying hierarchical data or comparing rows within the same
table. In a self-join, the same table is referenced multiple times in a query, allowing
for a comparison of rows based on a common attribute.
To illustrate the concept of self-joins, consider an example of an employees table
that contains information about employees and their managers. The table might have
the following columns: employee_id, name, and manager_id. Here, the manager_id
column refers to the employee_id of the employee's manager.
Suppose we want to retrieve a list of employees along with the names of their
respective managers. We can achieve this by performing a self-join on the
employees table. The SQL query would look like this:
SELECT e1.name AS Employee, e2.name AS Manager
FROM employees e1
JOIN employees e2 ON e1.manager_id = e2.employee_id;
In this query, e1 and e2 are aliases for the employees table. The JOIN condition
specifies that the manager_id from the first instance (e1) must match the
employee_id from the second instance (e2). The result will display each employee
alongside their manager’s name.
Self-joins can also be used for more complex queries, such as finding employees
who have the same manager. This can be done by grouping the results based on the
manager_id:
SELECT e1.manager_id, e1.name AS Employee1, e2.name AS Employee2
FROM employees e1
JOIN employees e2 ON e1.manager_id = e2.manager_id
WHERE e1.employee_id <> e2.employee_id;
This query retrieves pairs of employees who share the same manager, ensuring that
an employee is not compared with themselves by including the condition WHERE
e1.employee_id <> e2.employee_id.
Self-joins are powerful tools for analyzing data within a single table, enabling users
to extract valuable insights about relationships and hierarchies that exist in their
datasets.
Aggregation Functions
SQL aggregation functions are powerful tools that allow users to perform calculations
on a set of values and return a single value. These functions are essential for
summarizing data, making them invaluable in data analysis. Some of the most
commonly used aggregation functions include COUNT, SUM, AVG, MIN, and MAX.
COUNT
The COUNT function is used to determine the number of rows that match a specified
condition. For instance, if we want to count the total number of employees in a
company, the SQL query would be:
SELECT COUNT(*) AS TotalEmployees
FROM employees;
This query returns the total number of records in the employees table.
SUM
The SUM function calculates the total of a numeric column. For example, to find the
total sales from a sales table, the query would be:
SELECT SUM(quantity) AS TotalSales
FROM sales;
This query provides the total quantity sold across all transactions.
AVG
The AVG function computes the average value of a numeric column. To calculate
the average salary of employees, the following query can be used:
SELECT AVG(salary) AS AverageSalary
FROM employees;
This will return the mean salary value for all employees in the organization.
These queries return the minimum and maximum salary values, providing insights
into the compensation range within the organization.
Grouping Data with Aggregation Functions
Aggregation functions are often used in conjunction with the GROUP BY clause to
summarize data by specific categories. For example, if we want to calculate the total
sales for each product in the sales table, we can use:
SELECT product, SUM(quantity) AS TotalSales
FROM sales
GROUP BY product;
This will produce a summary of total sales for each product, allowing for effective
comparison and analysis.
In summary, SQL aggregation functions are crucial for data analysis, enabling users
to derive meaningful insights from their datasets through efficient summarization and
calculation.
Subqueries
Subqueries, also known as nested queries or inner queries, are SQL queries
embedded within another SQL query. They allow users to perform operations that
depend on the results of an outer query, enabling complex data retrieval and
manipulation in a structured manner. Subqueries can be used in various SQL
statements, including SELECT, INSERT, UPDATE, and DELETE, making them a
versatile tool in SQL programming.
The role of subqueries is primarily to filter or retrieve data based on criteria that are
derived from another query. This capability is particularly useful when the information
required cannot be obtained from a single query alone. Subqueries can be
categorized into two types: correlated and non-correlated. A non-correlated subquery
is independent of the outer query and can be executed on its own, while a correlated
subquery relies on the outer query for its values.
In this example, the inner query calculates the average salary of all employees, and
the outer query retrieves the names of those employees whose salaries exceed this
average.
In this example, the inner query calculates the average salary for each department
while the outer query checks each employee against their department's average
salary.
Subqueries enhance the ability to perform intricate queries, enabling data analysts
and developers to derive meaningful insights from relational databases effectively.
By leveraging subqueries, users can simplify complex logic and improve ++the
readability of their SQL commands.
Common Table Expressions (CTE)
Common Table Expressions (CTEs) are a powerful feature in SQL that provide a
way to create temporary result sets that can be referenced within a SELECT,
INSERT, UPDATE, or DELETE statement. A CTE is defined using the WITH clause,
followed by a query that generates the result set. This feature enhances the
readability and maintainability of SQL code, particularly for complex queries.
Benefits of CTEs
One of the primary benefits of using CTEs is their ability to simplify complex queries
by breaking them down into manageable parts. Instead of nesting multiple
subqueries, which can be challenging to read and debug, CTEs allow developers to
define a query once and reference it multiple times within a single SQL statement.
This not only improves clarity but also promotes code reuse.
Additionally, CTEs can be recursive, enabling users to perform hierarchical data
queries easily. This is particularly useful for applications that require reporting on
organizational structures, such as employee hierarchies.
Syntax of CTEs
The basic syntax for creating a CTE is as follows:
WITH cte_name AS (
SELECT column1, column2, ...
FROM table_name
WHERE condition
)
SELECT *
FROM cte_name;
In this syntax, cte_name represents the name of the CTE, and the query within
parentheses defines the result set.
Example of CTE
To illustrate the use of CTEs, consider a scenario where we want to retrieve the total
sales for each product from a sales table, and subsequently filter those results to
include only products with total sales greater than 100 units. The SQL query using a
CTE would look like this:
WITH ProductSales AS (
SELECT product, SUM(quantity) AS total_sales
FROM sales
GROUP BY product
)
SELECT *
FROM ProductSales
WHERE total_sales > 100;
In this example, the ProductSales CTE calculates the total quantity sold for each
product. The outer query then filters the results to show only those products with
total sales exceeding 100 units.
CTEs enhance query organization and clarity, making it easier for developers to
construct, read, and maintain complex SQL statements efficiently.
Window Functions
Window functions in SQL are a powerful feature that allows for advanced data
analysis without the need for complex subqueries or joins. Unlike traditional
aggregate functions that return a single result for a group of rows, window functions
operate on a set of rows defined by the OVER() clause, enabling users to perform
calculations across a specified range of data while still returning the individual row
results.
In this example, the SUM() function computes the cumulative sales for each product,
partitioned by the product column and ordered by sale_date. The result will show
each sale along with its cumulative total up to that point in time.
This query returns one result per product, which is useful for summary reports but
does not retain the detailed transaction information. In contrast, the window function
retains all original rows while adding the cumulative sales information, allowing for
more detailed analysis without losing context.
Conclusion
Window functions enhance SQL's analytical capabilities, allowing users to perform
complex calculations over specific data partitions while maintaining the integrity of
the original dataset. This makes them invaluable for data analysts and anyone
needing to perform sophisticated data analysis in relational databases.
Analytical Functions
Analytical functions in SQL are a powerful tool that enables complex calculations
across a set of rows related to the current row, providing richer insights into data
patterns and trends. Unlike standard aggregate functions, which summarize data into
a single output row, analytical functions return results for each row within the context
of its larger dataset. This capability is essential for tasks such as calculating running
totals, ranking items, and performing moving averages.
One of the most commonly used analytical functions is ROW_NUMBER(), which
assigns a unique sequential integer to rows within a partition of a result set. For
example, if you have a table of sales records and you want to rank each sale within
its respective product category by the sale date, you can use:
SELECT
product,
sale_date,
ROW_NUMBER() OVER (PARTITION BY product ORDER BY sale_date) AS
sale_rank
FROM
sales;
In this query, ROW_NUMBER() generates a rank for each sale per product, allowing
analysts to see the chronological order of sales within each category.
Another popular analytical function is SUM() used with the OVER() clause, which
calculates a cumulative total across a specified window. For example, to compute a
running total of sales quantities, you could write:
SELECT
sale_date,
product,
quantity,
SUM(quantity) OVER (ORDER BY sale_date) AS running_total
FROM
sales;
This query provides a total of all quantities sold up to each sale date, giving insight
into sales trends over time.
Moreover, the LAG() and LEAD() functions allow users to access data from the
previous or subsequent row, which is particularly useful for comparing values across
rows. For instance, to find the difference in sales quantity from one day to the next,
you could use:
SELECT
sale_date,
product,
quantity,
LAG(quantity) OVER (PARTITION BY product ORDER BY sale_date) AS
previous_quantity,
quantity - LAG(quantity) OVER (PARTITION BY product ORDER BY sale_date)
AS quantity_change
FROM
sales;
In this case, LAG(quantity) retrieves the quantity from the previous sale, enabling the
calculation of changes in sales volume day over day.
Overall, analytical functions enhance the capabilities of SQL for data analysis,
allowing users to perform sophisticated calculations that provide deeper insights into
their datasets without sacrificing the detail of individual records.
Views in SQL
Views in SQL are virtual tables that represent the result of a query. They allow users
to encapsulate complex SQL queries, thereby simplifying data access and
enhancing security. A view does not store data itself; instead, it dynamically retrieves
data from the underlying tables whenever accessed. This abstraction layer can
significantly streamline querying processes, as users can interact with a simplified
representation of data without needing to understand the underlying complexities.
Creating a View
Creating a view involves using the CREATE VIEW statement, followed by the view
name and the SQL query that defines the view. Here’s an example of how to create
a view:
CREATE VIEW EmployeeSales AS
SELECT e.name, e.department, SUM(s.quantity) AS TotalSales
FROM employees e
JOIN sales s ON e.employee_id = s.employee_id
GROUP BY e.name, e.department;
In this example, the EmployeeSales view summarizes total sales for each employee,
providing a clear overview of sales performance by department.
Using a View
To query a view, the syntax is similar to querying a regular table. For example, to
retrieve all employees with total sales greater than 100, you would execute:
SELECT * FROM EmployeeSales WHERE TotalSales > 100;
Views serve as an essential tool in SQL, offering a way to simplify complex queries,
enhance security, and provide a consistent interface for data access, making them
invaluable for database management and reporting.
CASE Statements
In SQL, CASE statements provide a way to implement conditional logic within
queries, allowing users to return specific values based on varying conditions. This
functionality is especially useful for categorizing data or generating computed
columns based on certain criteria. The basic syntax of a CASE statement can be
structured as follows:
SELECT column1,
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
...
ELSE default_result
END AS alias_name
FROM table_name;
In this example, the query categorizes products based on the quantity sold, allowing
for straightforward analysis of sales performance.
This query aggregates only the quantities that fall into the 'High Sales' category,
offering a focused insight into the highest-performing products.
Example 3: Dynamic Pricing Strategy
Another scenario could involve adjusting prices based on sales volume. For
instance, if we want to apply a discount based on quantity sold, we could implement
a CASE statement as follows:
SELECT product,
quantity,
price,
CASE
WHEN quantity > 100 THEN price * 0.9 -- 10% discount
WHEN quantity BETWEEN 51 AND 100 THEN price * 0.95 -- 5%
discount
ELSE price
END AS adjusted_price
FROM sales;
In this query, the adjusted_price column dynamically calculates the price based on
the quantity sold, applying discounts accordingly.
Overall, CASE statements in SQL are powerful tools for incorporating conditional
logic within queries, enhancing the ability to analyze and report data in meaningful
ways.
Creating Tables Using CTAS
The CREATE TABLE AS SELECT (CTAS) statement is a powerful SQL command
that allows users to create a new table based on the result set of a SELECT query.
This command is particularly useful for creating a snapshot of existing data or for
generating temporary tables for further analysis. The CTAS statement combines the
creation of a new table with the insertion of data into it, simplifying the process of
table creation and data population.
Syntax of CTAS
The basic syntax for using the CTAS statement is as follows:
CREATE TABLE new_table_name AS
SELECT column1, column2, ...
FROM existing_table_name
WHERE condition;
In this syntax, new_table_name is the name of the table to be created, and the
SELECT query determines which data is copied into the new table.
This query creates a new table called sales_archive containing all sales
records from prior to 2023.
This query generates a new table that holds the total sales figures for each
product, making it easier to access summarized data without repeatedly
executing complex queries.
This command creates a new table with only the records that passed a quality
check, allowing users to focus on high-quality data.
Conclusion
The CTAS statement is an effective tool for creating new tables efficiently while
simultaneously populating them with data from existing tables. By leveraging this
command, users can streamline various data management tasks, such as archiving,
summarizing, and transforming data, ultimately enhancing their workflow and
productivity in database management.
Temporary Tables
Temporary tables are a powerful feature in SQL that allows users to create tables
that exist temporarily during a session. They are particularly useful for storing
intermediate results or for data that is only needed for a short duration, such as
during complex queries or data processing tasks. These tables help streamline data
manipulation and enhance performance by avoiding repeated calculations or data
retrieval operations.
Use Cases
Temporary tables are commonly used in scenarios such as:
• Complex Data Manipulation: When performing intricate data
transformations, temporary tables can be used to hold intermediate results,
making it easier to manage the data flow.
• Staging Data for Processing: When importing or exporting data, temporary
tables can serve as staging areas where data can be cleaned or transformed
before final insertion into permanent tables.
• Simplifying Queries: For complex queries that require multiple steps,
temporary tables can simplify the SQL code by breaking down the process
into manageable parts.
Benefits
The benefits of using temporary tables include:
• Performance Improvement: By storing intermediate results in a temporary
table, you can reduce the need for repeated calculations, which can enhance
query performance.
• Isolation: Temporary tables are session-specific, meaning that they do not
interfere with the data in permanent tables. This characteristic is ideal for
testing and development.
• Ease of Use: Temporary tables allow for easier coding and maintenance by
providing a structured way to handle intermediate data.
For example, to create a temporary table to hold sales data, you could use:
CREATE TEMPORARY TABLE temp_sales (
product_id INT,
quantity_sold INT,
sale_date DATE
);
You can then perform operations on the temporary table just like any other table,
such as querying it to retrieve data:
SELECT * FROM temp_sales
WHERE quantity_sold > 150;
Once the session ends or the temporary table is no longer needed, it is automatically
dropped, ensuring that there is no residual data lingering in the database.
Temporary tables are an invaluable tool for SQL developers and database
administrators, facilitating efficient data handling and enhancing the overall
performance of database operations.
Creates a table
A stored SQL A temporary A table that
based on a
Definition query that does result set used exists only in the
SELECT
not store data. within a query. session.
statement.
Permanent
Permanent
Only lasts during (unless it's Exists only for
Persistence (unless it's a
query execution. explicitly the session.
transient view).
dropped).
No storage;
No storage; it Physically stores Stores data for
created in
Storage fetches data the data in a the session
memory during
dynamically. table. duration.
query execution.
Use Case Used for Used for Used to create a Used for
reusable query simplifying new table from intermediate
CTE (Common CTAS (Create
Temporary
Feature View Table Table As
Table
Expression) Select)
logic and
an existing processing
security (data complex queries.
dataset. within a session.
masking).
Faster for
Slightly slower Faster as data is
temporary use Faster as data is
Performance as it queries data stored, but only
but does not materialized.
dynamically. for the session.
persist.
In this case, the integer 10 is implicitly cast to a float for the addition operation,
allowing the operation to complete without any errors.
Explicit Casting
Explicit casting, on the other hand, requires the user to define the desired data type
for the conversion explicitly. This is done using the CAST() or CONVERT() functions.
Explicit casting is important when the conversion might lead to data loss or when the
user needs to ensure that the data conforms to a specific format. For example:
SELECT CAST(10 AS VARCHAR(10)) AS StringValue; -- Result: '10'
In this example, a string in the format of a date is converted to a DATE data type,
allowing for proper date comparisons and operations in subsequent queries.
Proper use of data type casting enhances data integrity and accuracy in SQL
queries, allowing developers to manipulate and analyze data effectively across
various data types.
Date Functions
SQL offers numerous functions for manipulating date and time data:
• GETDATE(): Returns the current date and time.
SELECT GETDATE() AS CurrentDateTime;
By mastering date and time handling in SQL, users can perform sophisticated
temporal analyses and maintain accurate records crucial for various applications.
Stored Procedures in SQL
5. Summary
Final Thoughts
✅ Use stored procedures to improve SQL Server efficiency.
✅ Follow best practices like input validation, modular design, and error handling.
✅ Stored procedures help with scalability, security, and performance tuning.
Creating Tables
name VARCHAR(100),
department VARCHAR(50),
salary DECIMAL(10,2),
);
name VARCHAR(100),
email VARCHAR(100)
);
customer_id INT,
order_date DATE,
);
product_name VARCHAR(100),
price DECIMAL(10,2)
);
order_id INT,
product_id INT,
quantity INT,
);
Inserting Data
INSERT INTO employees VALUES (1, 'John Doe', 'Sales', 60000, NULL);
INSERT INTO employees VALUES (2, 'Jane Smith', 'Marketing', 70000, 1);
INSERT INTO employees VALUES (3, 'Bob Brown', 'Sales', 50000, 1);
Beginner Exercises
1. Basic SELECT Query: Retrieve all columns from the employees table.
Intermediate Exercises
4. Aggregation with GROUP BY: Find the total number of orders placed by
each customer.
FROM orders
GROUP BY customer_id;
5. Using JOINs: List all orders along with the customer names.
FROM orders
SELECT name
FROM employees
Advanced Exercises
SELECT name,
CASE
ELSE 'Low'
END AS salary_category
FROM employees;
8. CTE for Hierarchical Data: List all employees and their managers.
WITH EmployeeHierarchy AS (
FROM employees
UNION ALL
FROM employees e
(Note: base case, no manager, top level union with recursive case)
Check down
1 CTE, row_number(),Delete
11. How do you fetch the 3rd highest salary in each department?
Cte – dense_rank()
Dense_rank is recommended)
FROM (
FROM employees
) temp
WHERE rnk = 3;
WITH RankedSalaries AS (
SELECT
department,
name,
salary,
DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS
rank
FROM employees
FROM RankedSalaries
WHERE rank = 3;
WITH SalaryRank AS (
SELECT salary,
FROM employees
SELECT salary
FROM SalaryRank
WHERE rnk = N;
FROM employees
13. Write a query to fetch all employee details where the employee
ID is even.
This method assigns a row number to each duplicate and deletes those with
row numbers greater than 1.
WITH CTE AS (
SELECT *,
FROM employees
SELECT MIN(customer_id)
FROM customers
);
✅ Best for: Any database system (MySQL, SQL Server, PostgreSQL, Oracle)
WHERE EXISTS (
);
JOIN products p2
ON p1.product_name = p2.product_name
5. Deleting Duplicates from order_items Using TEMP TABLE (For Large Tables)
WHERE order_item_id IN (
);
);
✅ Best for: If you want to retain only unique records and reset the table.
8. Deleting Duplicates from orders Using DELETE with LIMIT (Batch Deletion
in MySQL)
WHERE order_id IN (
FROM orders
) AS temp
WHERE rn > 1
) LIMIT 1000;
JOIN
Let's explore all types of joins between T1 and T2 using Snowflake SQL.
Given Tables:
T1
ID
1
2
2
3
NULL
T2
ID
2
3
3
4
NULL
4. FULL OUTER JOIN (All from both tables, matching where possible)
SELECT T1.ID AS T1_ID, T2.ID AS T2_ID
FROM T1
FULL OUTER JOIN T2
ON T1.ID = T2.ID;
🔹 Result: 8
T1.ID T2.ID Reason for Match?
1 NULL No match in T2
2 2 Matches
2 2 Matches
3 3 Matches
3 3 Matches
NULL NULL T1’s NULL row does not match anything but appears in FULL JOIN
NULL NULL T2’s NULL row does not match anything but appears in FULL JOIN
NULL 4 No match in T1
🔹 Explanation:
Includes all values from both tables.
1 (T1) and 4 (T2) have no match, so NULL appears.
NULL in both tables matches with NULL.
Summary of Joins
Join Type Includes NULLs? Matches Duplicates?
INNER JOIN No Yes
LEFT JOIN Yes (from T1) Yes
RIGHT JOIN Yes (from T2) Yes
FULL JOIN Yes (from both) Yes
CROSS JOIN No Yes (all combinations)
Answer:
FROM EMP
GROUP BY DEPT_NO
Answer: Yes, WHERE filters records before grouping, while HAVING filters
grouped records.
);
Answer:
Note: Column lists and their order must be the same in both queries.
Answer:
7. What is the difference between Primary Key, Unique Key, and Surrogate
Key?
Answer:
Primary Key: Unique + Not Null (only one per table, can be
composite).
Answer:
Answer:
Answer:
Answer:
Answer:
Answer:
Answer:
Answer:
Answer:
RANK – 1 2 2 4
DENSE RANK – 1 2 2 3
.
Thank You