Back to articles list Articles Cookbook
7 minutes read

How SQL Data Analysis Can Help You Understand Seasonality in Your Business

Your business data holds hidden seasonal patterns — sales peaks, slowdowns, and shifts that repeat every year. With just a few SQL queries, you can uncover these trends and turn them into smarter decisions. Here's how.

Every business experiences ups and downs — more sales in December, fewer customers in August, a spike in support tickets after a product update. These patterns are known as seasonality, and they can have a major impact on planning, staffing, marketing, and inventory.

If you're new to SQL, don’t worry. You can start with SQL Basics — it’s designed to help beginners understand how to write queries and explore data with confidence.

Seasonality isn’t just about holidays or the weather. It’s about recognizing predictable patterns in your business — and using them to your advantage.

For example:

  • Do your sales always dip in February?
  • Does traffic spike every September?
  • Are refunds consistently higher in January?

Many businesses guess at these trends. But with SQL, you can measure them — clearly, accurately, and without waiting on a BI dashboard.

In this article, we’ll show you how to uncover seasonal patterns in your data using SQL. You’ll follow a single example — an online clothing store called TrendyThreads — and learn how just a few smart queries can help you:

  • Spot seasonal spikes in revenue
  • Compare performance across years
  • Understand when and where different products sell best

Step 1: Make Sure You Have the Right Data

Before you start analyzing seasonality, you need one key ingredient: a column that tells you when something happened.

In SQL terms, that usually means a DATE or TIMESTAMP column — for example:

  • order_date in a sales table
  • visit_date in a website traffic log
  • signup_timestamp in a customer table

What’s the difference?

  • A DATE column stores only the calendar date (e.g., 2025-07-25).
  • A TIMESTAMP column includes both date and time (e.g., 2025-07-25 14:35:12).

SQL understands both types and can group them by day, week, month, or even hour. But be careful: if your dates are stored as plain text (like 'July 25'), you’ll need to convert them to a proper date format — otherwise SQL won’t group or filter them correctly.

At TrendyThreads, our fictional online clothing store, we’re working with an orders table that includes all sales from the past three years. Here’s a sample of the structure:

order_idorder_datetotal_amountproduct_categoryregion
10012023-01-0579.99JacketsNorth-East
10022023-03-1239.00T-ShirtsSouth
10032023-12-02120.00CoatsNorth-East
10042024-07-1959.99ShortsWest

Before diving into seasonal trends, it’s smart to check how much data you’re working with. You can do that with a simple query:

SELECT MIN(order_date), MAX(order_date)
FROM orders;

Result:

  • Earliest order: 2022-01-01
  • Most recent order: 2024-06-30

That gives us a solid three-year window — plenty of data to spot patterns.

📘 Want to get hands-on with working dates and times in SQL? Try Standard SQL Functions which has several sections on working with date and time data in SQL.

which has several sections on working with date and time data in SQL.

Here's a combined and polished version of “Spotting Seasonal Patterns with SQL” and “Step 2: Identify Monthly Sales Trends” — merged into a single cohesive section with smooth flow, beginner-friendly explanations, and a natural LearnSQL.com tone:

Once you’ve confirmed that your dataset includes a proper order_date column, you can start using SQL to uncover seasonal patterns — like which months bring in the most revenue.

Let’s say you want to answer a basic but important question:

“What are our total sales each month for the past three years?”

To do that, you’ll use three SQL tools:

  • YEAR(order_date) — to extract the year
  • MONTH(order_date) — to extract the month
  • GROUP BY — to group results by year and month

Here’s what the query looks like:

SELECT
  EXTRACT(YEAR FROM order_date) AS year,
  EXTRACT(MONTH FROM order_date) AS month,
  SUM(total_amount) AS revenue
FROM orders
GROUP BY year, month
ORDER BY year, month;

Example output:

yearmonthrevenue
202214,120.50
202223,080.00
202233,550.75
.........
2023127,940.25
202414,350.90

What you can learn:

  • December is your clear peak — revenue jumps by as much as 40%.
  • February consistently underperforms, confirming it’s your slowest month.
  • Sales rise steadily from September to November — possibly in anticipation of holiday shopping.

You suspected December was big — now you can prove it. This kind of insight helps you shift your marketing budget, plan stock levels, and align team efforts with real demand.

Want to build confidence with queries like this? Try Creating Basic SQL Reports.

Step 3: Compare Year-over-Year Performance

Spotting seasonal spikes is helpful — but there’s another key question to ask:

“Are those seasonal months actually growing over time?”

In other words:

  • Did December 2023 outperform December 2022?
  • Is April 2024 stronger than April 2023, or weaker?
    To answer that, you can compare each month’s revenue to the same month last year. SQL makes this possible using a powerful tool called a window function — specifically, LAG().

The LAG() function lets you look back at the previous row — in this case, the previous year’s revenue for the same month. It works like this:

  • You group your data by month and year
  • You order it by year
  • Then LAG() grabs the revenue from the previous year, within that same month

Here’s the query:

SELECT
  EXTRACT(YEAR FROM order_date) AS year,
  EXTRACT(MONTH FROM order_date) AS month,
  SUM(total_amount) AS revenue,
  LAG(SUM(total_amount)) OVER (
    PARTITION BY EXTRACT(MONTH FROM order_date)
    ORDER BY EXTRACT(YEAR FROM order_date)
  ) AS last_year_revenue
FROM orders
GROUP BY year, month
ORDER BY month, year;

Example output:

yearmonthrevenuelast_year_revenue
2022126,400.00NULL
2023128,000.006,400.00
2024129,150.008,000.00

What this tells you:

  • December 2023 grew 25% over December 2022 — great progress.
  • December 2024 added another 14% on top of that.
  • If you spot a month that’s shrinking year over year (like March), it’s a red flag worth investigating.

This is the power of window functions: you can compare rows without writing subqueries or joining the table to itself. Want to master techniques like this? Our interactive Window Functions course is your next step.

Knowing when customers spend is useful — but knowing what they buy during those months is even better.

Let’s say you want to answer questions like:

  • Which product categories peak during the winter?
  • Are shorts only popular in the summer?
  • Do some items sell steadily year-round?

Here’s the SQL query to uncover that:

SELECT
  product_category,
  EXTRACT(MONTH FROM order_date) AS month,
  SUM(total_amount) AS revenue
FROM orders
GROUP BY product_category, month
ORDER BY product_category, month;

This groups sales by product type and month — and adds up the revenue in each category.

Example output:

product_categorymonthrevenue
Coats114,500.00
Coats126,200.00
Shorts62,800.00
Shorts73,300.00
Shorts82,900.00
T-Shirts11,200.00
T-Shirts21,180.00
T-Shirts31,250.00
.........

What this tells you:

  • Coats and jackets sell best in November and December
  • Shorts dominate in the summer months
  • T-shirts have steady sales all year long

With this insight, you can:

  • Adjust inventory levels by season
  • Promote the right items at the right time
  • Avoid overstocking seasonal products in off-months

Want to sharpen your skills? Try our course Revenue Trend Analysis in SQL that helps you learn how to analyze trends with SQL.

Step 5: Understand Regional Patterns

Seasonality doesn’t look the same everywhere.

If you sell across different parts of the country — or to different customer types — patterns might vary dramatically. SQL lets you dig into those differences by grouping data by region, product category, or even customer segment.

Let’s explore this question:

“Do people in the South buy winter coats like customers in the North?”

Here’s how you can check:

SELECT
  region,
  EXTRACT(MONTH FROM order_date) AS month,
  SUM(total_amount) AS revenue
FROM orders
WHERE product_category IN ('Coats', 'Jackets')
GROUP BY region, month
ORDER BY region, month;

Example output

regionmonthrevenue
North-East114,100.00
North-East125,800.00
South111,200.00
South121,350.00
West122,300.00

What this tells you:

  • Northern regions show clear spikes in November and December
  • Southern customers buy fewer coats — even in winter
  • The West falls somewhere in between

Why it matters:

  • Don’t spend ad budget promoting winter gear in regions where it won’t move
  • Localize your email campaigns and homepage banners by geography
  • Send more inventory north — and save space down south

Want to try more of this kind of grouped analysis? SQL GROUP BY Practice gives you real business scenarios to solve with SQL.

From Data to Action

Seasonal trends are hiding in your data — SQL helps you uncover them. You don’t need fancy tools or a data science degree. Just access to your data, a date column, and a few well-written queries.

In a few steps, you’ve learned how to:

  • Spot monthly spikes and dips
  • Compare performance year over year
  • See how products and regions behave differently

With that, you can plan ahead: stock smarter, time your campaigns, and make decisions based on facts — not guesses. Want to go further? Try the SQL for Data Analysis Track.

Every business has its rhythms. The trick is knowing yours — and SQL gives you the tools to do just that. Start practicing at LearnSQL.com and see what your data’s been trying to tell you.