YOY এবং QOQ
YOY এবং QOQ — সম্পূর্ণ ব্যাখ্যা 📖
১. আগে একটা Real Story দিয়ে শুরু করি
🏪 ধরো FoodBD App এর CEO Meeting
CEO জিজ্ঞেস করলো —
"এই জানুয়ারিতে আমাদের Revenue ৳৫,০০,০০০ হয়েছে। এটা কি ভালো না খারাপ?"
তুমি বললে —
"৳৫,০০,০০০ হয়েছে Sir।"
CEO বললো —
"শুধু সংখ্যা বললে হবে না! গত বছরের জানুয়ারিতে কত ছিলো? গত Quarter এ কত ছিলো? আমরা কি grow করছি নাকি পিছিয়ে যাচ্ছি?"
এই প্রশ্নের উত্তর দিতেই দরকার:
গত বছরের same সময়ের সাথে compare → YOY
গত Quarter এর সাথে compare → QOQ
২. YOY কী? (Year Over Year)
YOY মানে — এই বছরের একটা সময়কে ঠিক গত বছরের same সময়ের সাথে compare করা।
Formula:
এই বছরের Value - গত বছরের Value
YOY % = ─────────────────────────────────── × ১০০
গত বছরের Value
Simple Example:
জানুয়ারি ২০২৪ Revenue = ৳৫,০০,০০০
জানুয়ারি ২০২৩ Revenue = ৳৪,০০,০০০
YOY = (৫,০০,০০০ - ৪,০০,০০০) / ৪,০০,০০০ × ১০০
YOY = ১,০০,০০০ / ৪,০০,০০০ × ১০০
YOY = 25%
মানে — গত বছরের তুলনায় এই বছর ২৫% বেশি Revenue হয়েছে। 🚀
৩. কেন YOY দরকার? Seasonality এর কারণে
এটা বোঝাটা অনেক গুরুত্বপূর্ণ।
ধরো FoodBD এর Monthly Revenue:
মাস Revenue
─────────────────────
জানুয়ারি → ৳৩,০০,০০০
ফেব্রুয়ারি → ৳২,৫০,০০০ ← কমে গেছে! খারাপ?
মার্চ → ৳২,৮০,০০০
এপ্রিল → ৳৩,২০,০০০
মে → ৳৩,৫০,০০০
জুন → ৳৪,০০,০০০
জুলাই → ৳৬,০০,০০০ ← বেশি! ভালো? (ঈদ)
আগস্ট → ৳৩,০০,০০০ ← হঠাৎ কমে গেছে! খারাপ?
সমস্যা:
আগস্টে Revenue কমেছে ৳৬ লাখ থেকে ৳৩ লাখে।
কিন্তু এটা কি সত্যিই খারাপ?
না! কারণ:
জুলাইতে ঈদ ছিলো তাই বেশি ছিলো।
আগস্টে স্বাভাবিক হয়েছে।
এটাই Seasonality —
প্রতি বছর same সময়ে same pattern হয়।
সমাধান — YOY দেখো:
আগস্ট ২০২৪ Revenue = ৳৩,০০,০০০
আগস্ট ২০২৩ Revenue = ৳২,৫০,০০০
YOY = (৩,০০,০০০ - ২,৫০,০০০) / ২,৫০,০০০ × ১০০
YOY = 20% ✅
মানে — গত বছরের আগস্টের চেয়ে ২০% বেশি।
আসলে ভালোই হচ্ছে!
৪. QOQ কী? (Quarter Over Quarter)
আগে Quarter মানে বুঝি।
Quarter কী?
একটা বছরকে ৪ ভাগে ভাগ করলে প্রতিটা ভাগই এক Quarter।
Q1 = জানুয়ারি + ফেব্রুয়ারি + মার্চ
Q2 = এপ্রিল + মে + জুন
Q3 = জুলাই + আগস্ট + সেপ্টেম্বর
Q4 = অক্টোবর + নভেম্বর + ডিসেম্বর
QOQ মানে — এই Quarter কে ঠিক আগের Quarter এর সাথে compare করা।
Formula:
এই Quarter এর Value - আগের Quarter এর Value
QOQ % = ──────────────────────────────────────────────── × ১০০
আগের Quarter এর Value
Simple Example:
Q2 2024 Revenue = ৳১৫,০০,০০০
Q1 2024 Revenue = ৳১২,০০,০০০
QOQ = (১৫,০০,০০০ - ১২,০০,০০০) / ১২,০০,০০০ × ১০০
QOQ = ৩,০০,০০০ / ১২,০০,০০০ × ১০০
QOQ = 25%
মানে — আগের Quarter এর তুলনায় এই Quarter এ ২৫% বেশি Revenue। 🚀
৫. YOY vs QOQ — পার্থক্য কী?
┌─────────────────────┬──────────────────────────────────────┐
│ YOY │ QOQ │
├─────────────────────┼──────────────────────────────────────┤
│ গত বছরের same │ ঠিক আগের Quarter এর সাথে │
│ সময়ের সাথে compare │ compare করা │
├─────────────────────┼──────────────────────────────────────┤
│ Seasonality এর │ Short-term growth │
│ effect নেই │ দেখা যায় │
├─────────────────────┼──────────────────────────────────────┤
│ Long-term growth │ Recent trend ধরা যায় │
│ বোঝা যায় │ │
├─────────────────────┼──────────────────────────────────────┤
│ Example: │ Example: │
│ এই জানুয়ারি vs │ Q2 2024 vs Q1 2024 │
│ গত জানুয়ারি │ │
└─────────────────────┴──────────────────────────────────────┘
৬. Real Data দিয়ে দুইটা একসাথে বুঝি
FoodBD এর ২ বছরের Quarterly Revenue:
Quarter │ Revenue │ QOQ % │ YOY %
──────────┼───────────────┼───────────────┼───────────────
Q1 2023 │ ৳১০,০০,০০০ │ - │ -
Q2 2023 │ ৳১২,০০,০০০ │ +20% │ -
Q3 2023 │ ৳১৮,০০,০০০ │ +50% │ - (ঈদ)
Q4 2023 │ ৳১৪,০০,০০০ │ -22% │ -
──────────┼───────────────┼───────────────┼───────────────
Q1 2024 │ ৳১৩,০০,০০০ │ -7% │ +30% ✅
Q2 2024 │ ৳১৫,০০,০০০ │ +15% │ +25% ✅
Q3 2024 │ ৳২২,০০,০০০ │ +47% │ +22% ✅
Q4 2024 │ ৳১৮,০০,০০০ │ -18% │ +29% ✅
Analysis:
Q1 2024 এর QOQ = -7% (মনে হচ্ছে খারাপ)
কিন্তু YOY = +30% (আসলে অনেক ভালো!)
কারণ: Q4 তে সবসময় বেশি হয় (শীতকালীন উৎসব)
Q1 এ কমাটা স্বাভাবিক।
YOY দেখলে বোঝা যায় আসলে grow হচ্ছে।
Q3 তে QOQ = +47% (অনেক বেশি মনে হচ্ছে)
কিন্তু এটা প্রতি বছরই হয় (ঈদের কারণে)
YOY = +22% দেখলে বোঝা যায়
আগের বছরের ঈদের চেয়ে ২২% ভালো হয়েছে।
৭. আরেকটা Term — MOM (Month Over Month)
YOY আর QOQ এর সাথে MOM ও জেনে রাখো।
MOM = Month Over Month
এই মাস vs গত মাস
Formula:
MOM % = (এই মাস - গত মাস) / গত মাস × ১০০
Example:
ফেব্রুয়ারি Revenue = ৳৪,০০,০০০
জানুয়ারি Revenue = ৳৩,৫০,০০০
MOM = (৪,০০,০০০ - ৩,৫০,০০০) / ৩,৫০,০০০ × ১০০
MOM = 14.3%
তিনটা একসাথে কখন use করবে:
MOM → Short-term change দেখতে (প্রতি মাসে)
QOQ → Medium-term trend দেখতে (প্রতি Quarter এ)
YOY → Long-term growth দেখতে (বার্ষিক review এ)
৮. SQL দিয়ে Calculate করা
Query 1 — YOY Revenue
SELECT
current_year.month_name,
current_year.revenue AS revenue_2024,
previous_year.revenue AS revenue_2023,
-- YOY Change Amount
ROUND(
current_year.revenue -
previous_year.revenue
, 2) AS yoy_change,
-- YOY Percentage
ROUND(
(current_year.revenue - previous_year.revenue)
* 100.0 /
NULLIF(previous_year.revenue, 0)
, 2) AS yoy_percentage
FROM
-- এই বছরের data
(
SELECT
TO_CHAR(created_at, 'MM-Month') AS month_name,
EXTRACT(MONTH FROM created_at) AS month_num,
SUM(order_amount) AS revenue
FROM orders
WHERE EXTRACT(YEAR FROM created_at) = 2024
GROUP BY
TO_CHAR(created_at, 'MM-Month'),
EXTRACT(MONTH FROM created_at)
) current_year
JOIN
-- গত বছরের data
(
SELECT
TO_CHAR(created_at, 'MM-Month') AS month_name,
EXTRACT(MONTH FROM created_at) AS month_num,
SUM(order_amount) AS revenue
FROM orders
WHERE EXTRACT(YEAR FROM created_at) = 2023
GROUP BY
TO_CHAR(created_at, 'MM-Month'),
EXTRACT(MONTH FROM created_at)
) previous_year
ON current_year.month_num = previous_year.month_num
ORDER BY current_year.month_num;
Output:
month_name | revenue_2024 | revenue_2023 | yoy_change | yoy_percentage
--------------|--------------|--------------|-------------|---------------
01-January | 500000.00 | 400000.00 | 100000.00 | 25.00
02-February | 450000.00 | 380000.00 | 70000.00 | 18.42
03-March | 520000.00 | 410000.00 | 110000.00 | 26.83
04-April | 600000.00 | 470000.00 | 130000.00 | 27.66
05-May | 650000.00 | 500000.00 | 150000.00 | 30.00
Query 2 — QOQ Revenue
SELECT
quarter,
revenue,
-- আগের Quarter এর revenue (LAG function)
LAG(revenue) OVER (ORDER BY quarter) AS prev_quarter_revenue,
-- QOQ Change
ROUND(
revenue -
LAG(revenue) OVER (ORDER BY quarter)
, 2) AS qoq_change,
-- QOQ Percentage
ROUND(
(revenue - LAG(revenue) OVER (ORDER BY quarter))
* 100.0 /
NULLIF(LAG(revenue) OVER (ORDER BY quarter), 0)
, 2) AS qoq_percentage
FROM (
SELECT
TO_CHAR(created_at, 'YYYY')
|| '-Q'
|| TO_CHAR(created_at, 'Q') AS quarter,
SUM(order_amount) AS revenue
FROM orders
WHERE created_at >= NOW() - INTERVAL '2 years'
GROUP BY
TO_CHAR(created_at, 'YYYY')
|| '-Q'
|| TO_CHAR(created_at, 'Q')
) quarterly_data
ORDER BY quarter;
Output:
quarter | revenue | prev_quarter | qoq_change | qoq_percentage
---------|-------------|--------------|-------------|---------------
2023-Q1 | 1000000.00 | NULL | NULL | NULL
2023-Q2 | 1200000.00 | 1000000.00 | 200000.00 | 20.00
2023-Q3 | 1800000.00 | 1200000.00 | 600000.00 | 50.00
2023-Q4 | 1400000.00 | 1800000.00 | -400000.00 | -22.22
2024-Q1 | 1300000.00 | 1400000.00 | -100000.00 | -7.14
2024-Q2 | 1500000.00 | 1300000.00 | 200000.00 | 15.38
2024-Q3 | 2200000.00 | 1500000.00 | 700000.00 | 46.67
2024-Q4 | 1800000.00 | 2200000.00 | -400000.00 | -18.18
Query 3 — YOY + QOQ + MOM একসাথে
WITH monthly_revenue AS (
SELECT
DATE_TRUNC('month', created_at) AS month_start,
SUM(order_amount) AS revenue
FROM orders
GROUP BY DATE_TRUNC('month', created_at)
)
SELECT
TO_CHAR(month_start, 'YYYY-MM') AS month,
revenue AS current_revenue,
-- MOM
LAG(revenue, 1) OVER (ORDER BY month_start)
AS prev_month_revenue,
ROUND(
(revenue - LAG(revenue, 1) OVER (ORDER BY month_start))
* 100.0 /
NULLIF(LAG(revenue, 1) OVER (ORDER BY month_start), 0)
, 2) AS mom_pct,
-- YOY (১২ মাস আগের data)
LAG(revenue, 12) OVER (ORDER BY month_start)
AS same_month_last_year,
ROUND(
(revenue - LAG(revenue, 12) OVER (ORDER BY month_start))
* 100.0 /
NULLIF(LAG(revenue, 12) OVER (ORDER BY month_start), 0)
, 2) AS yoy_pct
FROM monthly_revenue
ORDER BY month_start DESC
LIMIT 12;
Output:
month | current_revenue | prev_month | mom_pct | last_year | yoy_pct
--------|-----------------|------------|---------|-----------|--------
2024-12 | 600000.00 | 550000.00 | +9.1% | 480000.00 | +25.0%
2024-11 | 550000.00 | 500000.00 | +10.0% | 440000.00 | +25.0%
2024-10 | 500000.00 | 480000.00 | +4.2% | 400000.00 | +25.0%
2024-09 | 480000.00 | 700000.00 | -31.4% | 380000.00 | +26.3%
2024-08 | 700000.00 | 650000.00 | +7.7% | 560000.00 | +25.0%
৯. Python দিয়ে Calculate করা
import pandas as pd
import psycopg2
conn = psycopg2.connect(
host="your-host",
database="your_db",
user="your_user",
password="your_password"
)
query = """
SELECT
DATE_TRUNC('month', created_at) AS month_start,
SUM(order_amount) AS revenue,
COUNT(*) AS total_orders
FROM orders
GROUP BY DATE_TRUNC('month', created_at)
ORDER BY month_start
"""
df = pd.read_sql(query, conn)
conn.close()
df['month_start'] = pd.to_datetime(df['month_start'])
df = df.sort_values('month_start').reset_index(drop=True)
# =============================================
# MOM CALCULATION
# =============================================
df['prev_month_revenue'] = df['revenue'].shift(1)
df['mom_change'] = df['revenue'] - df['prev_month_revenue']
df['mom_pct'] = (
df['mom_change'] / df['prev_month_revenue'] * 100
).round(2)
# =============================================
# YOY CALCULATION (১২ মাস আগে)
# =============================================
df['prev_year_revenue'] = df['revenue'].shift(12)
df['yoy_change'] = df['revenue'] - df['prev_year_revenue']
df['yoy_pct'] = (
df['yoy_change'] / df['prev_year_revenue'] * 100
).round(2)
# =============================================
# QUARTER COLUMN ADD করো
# =============================================
df['quarter'] = df['month_start'].dt.to_period('Q')
# QOQ CALCULATION
quarterly = df.groupby('quarter')['revenue'].sum().reset_index()
quarterly['prev_quarter_revenue'] = quarterly['revenue'].shift(1)
quarterly['qoq_change'] = (
quarterly['revenue'] - quarterly['prev_quarter_revenue']
)
quarterly['qoq_pct'] = (
quarterly['qoq_change'] /
quarterly['prev_quarter_revenue'] * 100
).round(2)
# =============================================
# PRINT REPORTS
# =============================================
print("============================================")
print(" YOY & MOM REPORT ")
print("============================================")
print(df[[
'month_start',
'revenue',
'mom_pct',
'yoy_pct'
]].tail(12).to_string(index=False))
print("\n============================================")
print(" QOQ REPORT ")
print("============================================")
print(quarterly.to_string(index=False))
# =============================================
# GROWTH SUMMARY
# =============================================
latest = df.iloc[-1]
print("\n============================================")
print(" GROWTH SUMMARY (Latest Month) ")
print("============================================")
print(f"Current Revenue : ৳{latest['revenue']:,.0f}")
print(f"MOM Growth : {latest['mom_pct']:+.1f}%")
print(f"YOY Growth : {latest['yoy_pct']:+.1f}%")
# Status check
if latest['yoy_pct'] > 20:
print("Overall Status : 🚀 Excellent Growth!")
elif latest['yoy_pct'] > 10:
print("Overall Status : ✅ Good Growth")
elif latest['yoy_pct'] > 0:
print("Overall Status : ⚠️ Slow Growth")
else:
print("Overall Status : ❌ Declining!")
Output:
============================================
YOY & MOM REPORT
============================================
month_start revenue mom_pct yoy_pct
2024-01-01 500000.00 +5.0% +25.0%
2024-02-01 450000.00 -10.0% +18.4%
2024-03-01 520000.00 +15.6% +26.8%
2024-04-01 600000.00 +15.4% +27.7%
2024-05-01 650000.00 +8.3% +30.0%
2024-06-01 700000.00 +7.7% +25.0%
============================================
QOQ REPORT
============================================
quarter revenue prev_qtr qoq_change qoq_pct
2023Q1 1000000.00 NaN NaN NaN
2023Q2 1200000.00 1000000.00 200000.00 20.00
2023Q3 1800000.00 1200000.00 600000.00 50.00
2023Q4 1400000.00 1800000.00 -400000.00 -22.22
2024Q1 1300000.00 1400000.00 -100000.00 -7.14
2024Q2 1500000.00 1300000.00 200000.00 15.38
============================================
GROWTH SUMMARY (Latest Month)
============================================
Current Revenue : ৳700,000
MOM Growth : +7.7%
YOY Growth : +25.0%
Overall Status : 🚀 Excellent Growth!
১০. ETL — Monthly Summary Table
# etl_growth_metrics.py
# প্রতি মাসের শুরুতে CRON এ run হবে
import psycopg2
from datetime import datetime
def calculate_growth_metrics():
conn = psycopg2.connect(
host="your-host",
database="your_db",
user="your_user",
password="your_password"
)
cursor = conn.cursor()
upsert_query = """
INSERT INTO growth_metrics_summary (
month_start,
revenue,
total_orders,
mom_pct,
yoy_pct
)
WITH monthly AS (
SELECT
DATE_TRUNC('month', created_at) AS month_start,
SUM(order_amount) AS revenue,
COUNT(*) AS total_orders
FROM orders
GROUP BY DATE_TRUNC('month', created_at)
)
SELECT
m.month_start,
m.revenue,
m.total_orders,
-- MOM
ROUND(
(m.revenue - prev_m.revenue)
* 100.0 / NULLIF(prev_m.revenue, 0)
, 2),
-- YOY
ROUND(
(m.revenue - prev_y.revenue)
* 100.0 / NULLIF(prev_y.revenue, 0)
, 2)
FROM monthly m
LEFT JOIN monthly prev_m
ON prev_m.month_start =
m.month_start - INTERVAL '1 month'
LEFT JOIN monthly prev_y
ON prev_y.month_start =
m.month_start - INTERVAL '12 months'
ON CONFLICT (month_start)
DO UPDATE SET
revenue = EXCLUDED.revenue,
total_orders = EXCLUDED.total_orders,
mom_pct = EXCLUDED.mom_pct,
yoy_pct = EXCLUDED.yoy_pct,
updated_at = NOW()
"""
cursor.execute(upsert_query)
conn.commit()
print(f"[{datetime.now()}] Growth Metrics ETL Complete.")
cursor.close()
conn.close()
if __name__ == "__main__":
calculate_growth_metrics()
সারসংক্ষেপ 🎯
| বিষয় | YOY | QOQ | MOM |
|---|---|---|---|
| মানে | Year over Year | Quarter over Quarter | Month over Month |
| Compare করে | গত বছরের same সময় | আগের Quarter | আগের মাস |
| কখন use করে | বার্ষিক growth দেখতে | Quarterly trend দেখতে | মাসিক change দেখতে |
| Seasonality | ❌ Effect নেই | ⚠️ কিছুটা আছে | ✅ Effect আছে |
| Formula | (এখন - তখন) / তখন × ১০০ | same | same |
এক কথায় মনে রাখো 🧠
MOM → "গত মাসের চেয়ে কেমন?" (Short-term)
QOQ → "গত Quarter এর চেয়ে কেমন?" (Medium-term)
YOY → "গত বছরের চেয়ে কেমন?" (Long-term, Seasonality নেই)
তিনটাই একসাথে দেখলে
পুরো business এর health বোঝা যায়। ✅