Header Ads

Header ADS

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 বোঝা যায়। ✅


Powered by Blogger.