12.1 - Advanced Database Operations
Advanced Database Operations
In this section, we'll explore some advanced database operations, including filtering, joining, grouping, aggregate functions, subqueries, Common Table Expressions (CTEs), data transactions, and set operations.
Filtering
Filtering involves retrieving specific rows from a database table that meet certain criteria. This is done using the WHERE
clause in SQL. In Drizzle, you can filter with where
along with eq
, ne
, gt
, lte
, isNull
, and/or
, between
, etc.
Use Case: Find products within a specific price range or with certain features.
export const getMenuItemById = async (db, id: number) => {
return await db.select().from(menuItems).where(eq(menuItems.id, id));
};
Joining
Joining combines rows from two or more tables based on a related column between them. The common types of joins are INNER JOIN
, LEFT JOIN
, RIGHT JOIN
, and FULL JOIN
.
Use Case: Combine data from the Customers
table and the Orders
table to get a list of all orders along with the customer details.
const userPosts = await db
.select()
.from(usersTable)
.leftJoin(postsTable, eq(usersTable.id, postsTable.userId));
Grouping
Grouping involves aggregating data based on one or more columns using the GROUP BY
clause. This is often used with aggregate functions like SUM
, AVG
, COUNT
, etc.
Use Case: Group sales data by product category to calculate the total sales for each category.
const salesByCategory = await db
.select({
category: salesTable.category,
totalAmount: sum(salesTable.amount),
})
.from(salesTable)
.groupBy(salesTable.category);
Aggregate Functions
Aggregate Functions perform calculations on a set of values and return a single value. Common aggregate functions include SUM
, AVG
, MAX
, MIN
, and COUNT
.
Use Case: Calculate the average order amount from the Orders
table.
const salesByCategory = await db
.select({
category: salesTable.category,
totalAmount: sum(salesTable.amount),
})
.from(salesTable)
.groupBy(salesTable.category);
Subqueries
Subqueries are queries nested inside another query. They are used to perform operations that require multiple steps.
Use Case: First find user ids of those who have made more than a certain number of purchases last month. And then use the user ids to find the corresponding user phone numbers.
const sq = db.select().from(users).where(eq(users.id, 42)).as("sq");
const result = await db.select().from(users).leftJoin(sq, eq(users.id, sq.id));
Common Table Expressions (CTEs)
Common Table Expressions (CTEs) are temporary result sets that can be referenced within a SELECT
, INSERT
, UPDATE
, or DELETE
statement. They are defined using the WITH
clause. Temporary result sets are defined within the scope of a single SQL statement and allow us to do further processing on this intermediary table.
Use Case: Create a temporary table with the customer id and total purchase amount for customers who have made purchases at the store for over 5 times in the past month. We then filter for customers whose purchase amount is greater than a certain value.
const sq = db.$with("sq").as(db.select().from(users).where(eq(users.id, 42)));
const result = await db.with(sq).select().from(sq);
Data Transactions
Data Transactions are sequences of database operations that are treated as a single unit. Transactions ensure data integrity by making sure that all operations succeed or if we fail at any point, we can rollback the steps that have already been taken. Transactions are managed using BEGIN
, COMMIT
, and ROLLBACK
.
Use Case: Ensure that all steps of a multi-step process (like transferring money between bank accounts) either complete successfully or none of them do.
await db.transaction(async (tx) => {
await tx.insert(usersTable).values({ name: "Alice" });
await tx.insert(accountsTable).values({ balance: 1000 });
});
Set Operations
Set Operations are used to combine the results of two or more queries. The common set operations are UNION
, INTERSECT
, and EXCEPT
.
Use Case: Combine results from two different queries to get a list of all unique customers who have made a purchase or have signed up for the newsletter.