Sling Academy
Home/Node.js/SequelizeJS: Grouping Results by Multiple Columns

SequelizeJS: Grouping Results by Multiple Columns

Last updated: February 19, 2024

Overview

In this guide, we’ll explore multiple approaches to grouping results by more than one column using Sequelize, an ORM (Object Relational Mapping) library for Node.js. Grouping is a powerful SQL feature that, when combined with Sequelize, can perform complex data retrieval tasks more efficiently.

Approach 1: Using raw SQL queries

Execute a raw SQL query to group results by multiple columns. This method allows for maximum flexibility but requires familiarity with raw SQL syntax.

  • Step 1: Import Sequelize and connect to your database.
  • Step 2: Use the .literal() method or .query() to execute a raw SQL grouping query.
  • Step 3: Map the results to a model if needed.

Example:

const result = await sequelize.query('SELECT count(*), column1, column2 FROM table GROUP BY column1, column2', { type: sequelize.QueryTypes.SELECT });
console.log(result);

Notes: While this approach offers great flexibility, it bypasses Sequelize’s abstractions, potentially leading to SQL injection vulnerabilities if not used carefully. Always use parameterized queries or the .literal() function to prevent these issues.

Approach 2: Using Sequelize aggregation methods

Utilize Sequelize’s built-in aggregation methods to group results. This method leverages Sequelize’s abstraction and is more secure against SQL injection.

  • Step 1: Define your model correctly if you haven’t already.
  • Step 2: Use the findAll() method combined with attributes and group options to perform the grouping.
  • Step 3: Optionally, include aggregate functions like SUM, AVERAGE in the attributes option to perform calculations on grouped data.

Example:

const result = await Model.findAll({
  attributes: [
    [sequelize.fn('COUNT', sequelize.col('id')), 'totalCount'],
    'column1',
    'column2'
  ],
  group: ['column1', 'column2']
});
console.log(result);

Notes: This method simplifies the process but might be less flexible than raw SQL in complex scenarios. Performance may vary depending on the complexity of the operations and the database schema.

Approach 3: Assembly of complex queries

For complex grouping involving extensive manipulation of the data, construct your query using subqueries or CTEs (Common Table Expressions).

  • Step 1: Strategically plan your query, identifying how best to segment the data processing.
  • Step 2: Use CTEs or subqueries within Sequelize raw queries or through the use of additional libraries that extend Sequelize’s capabilities.
  • Step 3: Execute the complex query and process the results.
// Example using a basic CTE with Sequelize's querying capabilities
const result = await sequelize.query(
"WITH GroupedData AS (SELECT column1, column2, COUNT(*) as TotalCount FROM table GROUP BY column1, column2) SELECT * FROM GroupedData",
  { type: sequelize.QueryTypes.SELECT }
);
console.log(result);

Notes: CTEs offer a way to write more readable and maintainable code for complex queries. However, understanding and designing CTEs can be challenging, and not all database engines may support them.

Conclusion

Grouping results by multiple columns in Sequelize demonstrates the flexibility and power of using an ORM for complex data manipulation and retrieval. Depending on your specific needs, you may opt for simplicity and security with Sequelize’s abstractions or dive into raw SQL for customized, granular control. Each method has its own set of trade-offs in terms of flexibility, performance, and security. Consider your project’s requirements and your level of comfort with SQL when deciding which approach to take.

Previous Article: How to Use Column Aliases in Sequelize.js

Series: Sequelize.js Tutorials

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates
  • ExpressJS: How to pass variables to Pug templates