Input: Quel est le volume de commandes validées qui n'ont pas encore été chargées ?

Output:
SELECT SUM(OrderQty) AS VolumeCommandesNonChargees
FROM FactOrders
WHERE IsStocked = 1
  AND IsDelivered = 0;


Input: Quelle est la différence entre le poids théorique et le poids réel chargé hier ?

Output:
DECLARE @yesterdayDate DATE = DATEADD(day, -1, CAST(GETDATE() AS DATE));

WITH TheoreticalWeight AS (
    SELECT SUM(p.Weight * o.OrderQty) AS TheoreticalWeight
    FROM FactOrders o
    INNER JOIN DimProduct p ON o.ProductKey = p.ProductKey
    INNER JOIN DimDate d ON o.OrderDateKey = d.date_key
    WHERE d.full_date = @yesterdayDate
),
RealWeight AS (
    SELECT SUM(p.Weight * fd.QuantiteDelivered) AS RealWeight
    FROM FactDelivery fd
    INNER JOIN DimProduct p ON fd.ProductKey = p.ProductKey
    INNER JOIN DimDate d ON fd.DeliveredDateKey = d.date_key
    WHERE d.full_date = @yesterdayDate
)
SELECT
    ISNULL(t.TheoreticalWeight, 0) - ISNULL(r.RealWeight, 0) AS WeightDifference,
    ISNULL(t.TheoreticalWeight, 0) AS TheoreticalWeight,
    ISNULL(r.RealWeight, 0) AS RealWeight
FROM TheoreticalWeight t
FULL OUTER JOIN RealWeight r ON 1 = 1;


Input: Quels articles ont été livrés à plus de 5 clients différents cette semaine ?

Output:
SELECT
    p.ProductID,
    p.ProductName,
    COUNT(DISTINCT fd.CustomerKey) AS DistinctCustomers
FROM FactDelivery fd
JOIN DimDate d ON fd.DeliveredDateKey = d.date_key
JOIN DimProduct p ON fd.ProductKey = p.ProductKey
WHERE DATEDIFF(week, 0, d.full_date) = DATEDIFF(week, 0, GETDATE())
GROUP BY p.ProductID, p.ProductName
HAVING COUNT(DISTINCT fd.CustomerKey) > 5
ORDER BY DistinctCustomers DESC;


Input: Quel est l'écart de chiffre d'affaires entre ce mois-ci et le même mois l'année dernière ?

Output:
WITH CA AS (
    SELECT
        SUM(CASE WHEN d.[year] = YEAR(GETDATE()) AND d.month_num_in_year = MONTH(GETDATE()) THEN f.AmountAfterDiscount END) AS CurrentCA,
        SUM(CASE WHEN d.[year] = YEAR(GETDATE()) - 1 AND d.month_num_in_year = MONTH(GETDATE()) THEN f.AmountAfterDiscount END) AS PrevCA
    FROM FactOrders f
    JOIN DimDate d ON f.OrderDateKey = d.date_key
)
SELECT
    CurrentCA,
    PrevCA,
    (CurrentCA - PrevCA) AS CA_Difference
FROM CA;


Input: Avons-nous vendu plus de quantités ce trimestre par rapport au même trimestre en 2025 ?

Output:
WITH CurrentQuarter AS (
    SELECT SUM(fo.OrderQty) AS Qty
    FROM FactOrders fo
    JOIN DimDate dd ON fo.OrderDateKey = dd.date_key
    WHERE dd.year = YEAR(GETDATE())
      AND dd.quarter = DATEPART(QUARTER, GETDATE())
),
SameQuarter2025 AS (
    SELECT SUM(fo.OrderQty) AS Qty
    FROM FactOrders fo
    JOIN DimDate dd ON fo.OrderDateKey = dd.date_key
    WHERE dd.year = 2025
      AND dd.quarter = DATEPART(QUARTER, GETDATE())
)
SELECT
    cq.Qty AS CurrentQuarterQty,
    sq2025.Qty AS SameQuarter2025Qty,
    CASE WHEN cq.Qty > sq2025.Qty THEN 1 ELSE 0 END AS IsHigherThan2025
FROM CurrentQuarter cq
CROSS JOIN SameQuarter2025 sq2025;


Input: Quels produits ont perdu plus de 20% de volume de vente par rapport à l'an passé à la même date ?

Output:
WITH CurrentYear AS (
    SELECT fo.ProductKey,
           SUM(fo.OrderQty) AS CurrQty
    FROM FactOrders fo
    JOIN DimDate d ON fo.OrderDateKey = d.date_key
    WHERE YEAR(d.full_date) = YEAR(GETDATE())
      AND MONTH(d.full_date) = MONTH(GETDATE())
      AND DAY(d.full_date) = DAY(GETDATE())
    GROUP BY fo.ProductKey
),
PrevYear AS (
    SELECT fo.ProductKey,
           SUM(fo.OrderQty) AS PrevQty
    FROM FactOrders fo
    JOIN DimDate d ON fo.OrderDateKey = d.date_key
    WHERE YEAR(d.full_date) = YEAR(GETDATE()) - 1
      AND MONTH(d.full_date) = MONTH(GETDATE())
      AND DAY(d.full_date) = DAY(GETDATE())
    GROUP BY fo.ProductKey
)
SELECT p.ProductID,
       p.ProductName,
       py.PrevQty,
       cy.CurrQty,
       (CAST(py.PrevQty - cy.CurrQty AS float) / NULLIF(py.PrevQty, 0)) * 100 AS PercentLoss
FROM PrevYear py
JOIN CurrentYear cy ON py.ProductKey = cy.ProductKey
JOIN DimProduct p ON p.ProductKey = py.ProductKey
WHERE py.PrevQty > 0
  AND (CAST(py.PrevQty - cy.CurrQty AS float) / py.PrevQty) > 0.20;


Input: Quelle région affiche la meilleure croissance annuelle du chiffre d'affaires par rapport à l'année dernière ?

Output:
WITH CA_By_Region_Year AS (
    SELECT g.Region,
           d.year,
           SUM(o.AmountAfterDiscount) AS CA
    FROM FactOrders o
    JOIN DimDate d ON o.OrderDateKey = d.date_key
    JOIN DimGeography g ON o.GeographyKey = g.GeographyID
    GROUP BY g.Region, d.year
),
Growth AS (
    SELECT cur.Region,
           ((cur.CA - prev.CA) / NULLIF(prev.CA, 0)) * 100.0 AS GrowthPct,
           cur.year AS CurrentYear,
           prev.year AS PreviousYear
    FROM CA_By_Region_Year cur
    JOIN CA_By_Region_Year prev
      ON cur.Region = prev.Region
     AND cur.year = prev.year + 1
)
SELECT TOP 1
    Region,
    GrowthPct,
    CurrentYear,
    PreviousYear
FROM Growth
ORDER BY GrowthPct DESC;


Input: Combien de nouveaux clients avons-nous ce mois-ci par rapport au mois précédent ?

Output:
SELECT
    COUNT(*) AS NewClientsCurrentMonth,
    (SELECT COUNT(*) FROM DimCustomer
        WHERE FirstOrderDate IS NOT NULL
          AND YEAR(FirstOrderDate) = YEAR(DATEADD(MONTH, -1, GETDATE()))
          AND MONTH(FirstOrderDate) = MONTH(DATEADD(MONTH, -1, GETDATE()))
    ) AS NewClientsPreviousMonth,
    COUNT(*) - (SELECT COUNT(*) FROM DimCustomer
        WHERE FirstOrderDate IS NOT NULL
          AND YEAR(FirstOrderDate) = YEAR(DATEADD(MONTH, -1, GETDATE()))
          AND MONTH(FirstOrderDate) = MONTH(DATEADD(MONTH, -1, GETDATE()))
    ) AS Difference
FROM DimCustomer
WHERE FirstOrderDate IS NOT NULL
  AND YEAR(FirstOrderDate) = YEAR(GETDATE())
  AND MONTH(FirstOrderDate) = MONTH(GETDATE());


Input: Le panier moyen a-t-il augmenté ou diminué par rapport à l'année dernière ?

Output:
WITH OrderTotals AS (
    SELECT
        fo.SalesOrderNum,
        SUM(fo.AmountAfterDiscount) AS OrderTotal,
        d.year AS OrderYear
    FROM FactOrders fo
    JOIN DimDate d ON fo.OrderDateKey = d.date_key
    GROUP BY fo.SalesOrderNum, d.year
)
SELECT
    AVG(CASE WHEN OrderYear = YEAR(GETDATE()) THEN OrderTotal END) AS AvgBasketCurrentYear,
    AVG(CASE WHEN OrderYear = YEAR(GETDATE()) - 1 THEN OrderTotal END) AS AvgBasketPrevYear,
    CASE
        WHEN AVG(CASE WHEN OrderYear = YEAR(GETDATE()) THEN OrderTotal END) > AVG(CASE WHEN OrderYear = YEAR(GETDATE()) - 1 THEN OrderTotal END) THEN 'Increase'
        WHEN AVG(CASE WHEN OrderYear = YEAR(GETDATE()) THEN OrderTotal END) < AVG(CASE WHEN OrderYear = YEAR(GETDATE()) - 1 THEN OrderTotal END) THEN 'Decrease'
        ELSE 'No Change'
    END AS Trend
FROM OrderTotals
WHERE OrderYear IN (YEAR(GETDATE()), YEAR(GETDATE()) - 1);


Input: Quels vendeurs ont dépassé leur performance de l'année dernière sur la même période ?

Output:
WITH CurrentSales AS (
    SELECT o.EmployeeKey,
           SUM(o.AmountAfterDiscount) AS SalesCurrent
    FROM FactOrders o
    JOIN DimDate d ON o.OrderDateKey = d.date_key
    WHERE d.full_date >= DATEFROMPARTS(YEAR(GETDATE()), 1, 1)
      AND d.full_date <= GETDATE()
    GROUP BY o.EmployeeKey
),
LastSales AS (
    SELECT o.EmployeeKey,
           SUM(o.AmountAfterDiscount) AS SalesLast
    FROM FactOrders o
    JOIN DimDate d ON o.OrderDateKey = d.date_key
    WHERE d.full_date >= DATEADD(year, -1, DATEFROMPARTS(YEAR(GETDATE()), 1, 1))
      AND d.full_date <= DATEADD(year, -1, GETDATE())
    GROUP BY o.EmployeeKey
)
SELECT e.EmployeeID,
       e.EmployeeFullName,
       cs.SalesCurrent,
       ls.SalesLast,
       cs.SalesCurrent - ls.SalesLast AS SalesIncrease
FROM CurrentSales cs
JOIN LastSales ls ON cs.EmployeeKey = ls.EmployeeKey
JOIN DimEmployee e ON cs.EmployeeKey = e.EmployeeKey
WHERE cs.SalesCurrent > ls.SalesLast
ORDER BY SalesIncrease DESC;


Input: Quelle est l'évolution du nombre de commandes entre ce lundi et le lundi de la semaine dernière ?

Output:
SET DATEFIRST 1;
DECLARE @Today date = CAST(GETDATE() AS date);
DECLARE @ThisMonday date = DATEADD(day, 1 - DATEPART(weekday, @Today), @Today);
DECLARE @LastMonday date = DATEADD(day, -7, @ThisMonday);

SELECT
    @ThisMonday AS MondayDate,
    COUNT(DISTINCT CASE WHEN D.full_date = @ThisMonday THEN FO.SalesOrderNum END) AS OrderCount,
    @LastMonday AS PreviousMondayDate,
    COUNT(DISTINCT CASE WHEN D.full_date = @LastMonday THEN FO.SalesOrderNum END) AS PreviousOrderCount,
    (COUNT(DISTINCT CASE WHEN D.full_date = @ThisMonday THEN FO.SalesOrderNum END) -
     COUNT(DISTINCT CASE WHEN D.full_date = @LastMonday THEN FO.SalesOrderNum END)) AS Difference,
    CASE WHEN COUNT(DISTINCT CASE WHEN D.full_date = @LastMonday THEN FO.SalesOrderNum END) = 0 THEN NULL
         ELSE CAST( (COUNT(DISTINCT CASE WHEN D.full_date = @ThisMonday THEN FO.SalesOrderNum END) -
                     COUNT(DISTINCT CASE WHEN D.full_date = @LastMonday THEN FO.SalesOrderNum END)) * 100.0 /
                    COUNT(DISTINCT CASE WHEN D.full_date = @LastMonday THEN FO.SalesOrderNum END)
               AS decimal(10,2))
    END AS PercentChange
FROM FactOrders FO
JOIN DimDate D ON FO.OrderDateKey = D.date_key
WHERE D.full_date IN (@ThisMonday, @LastMonday);


Input: Quels clients n'ont rien acheté ce mois-ci alors qu'ils étaient dans le Top 10 l'an dernier ?

Output:
WITH LastYearSales AS (
    SELECT fo.CustomerKey,
           SUM(fo.AmountAfterDiscount) AS TotalSales
    FROM FactOrders fo
    JOIN DimDate d ON fo.OrderDateKey = d.date_key
    WHERE d.year = YEAR(GETDATE()) - 1
    GROUP BY fo.CustomerKey
),
Top10Customers AS (
    SELECT TOP (10) CustomerKey
    FROM LastYearSales
    ORDER BY TotalSales DESC
),
CurrentMonthSales AS (
    SELECT DISTINCT fo.CustomerKey
    FROM FactOrders fo
    JOIN DimDate d ON fo.OrderDateKey = d.date_key
    WHERE d.year = YEAR(GETDATE())
      AND d.month_num_in_year = MONTH(GETDATE())
)
SELECT dc.CustomerKey,
       dc.CustomerFullName,
       dc.CustomerCode,
       dc.CustomerReference
FROM Top10Customers t
JOIN DimCustomer dc ON t.CustomerKey = dc.CustomerKey
LEFT JOIN CurrentMonthSales cms ON t.CustomerKey = cms.CustomerKey
WHERE cms.CustomerKey IS NULL;


Input: Quelle famille de produits a la plus forte progression de ventes par rapport à l'année passée ?

Output:
WITH SalesByFamily AS (
    SELECT f.FamilleKey,
           fam.FamilleName,
           YEAR(d.full_date) AS SalesYear,
           SUM(o.AmountAfterDiscount) AS SalesAmount
    FROM FactOrders o
    INNER JOIN DimDate d ON o.OrderDateKey = d.date_key
    INNER JOIN DimProduct p ON o.ProductKey = p.ProductKey
    INNER JOIN DimFamille f ON p.FamilleKey = f.FamilleKey
    INNER JOIN DimFamille fam ON f.FamilleKey = fam.FamilleKey
    WHERE YEAR(d.full_date) IN (YEAR(GETDATE()), YEAR(GETDATE()) - 1)
    GROUP BY f.FamilleKey, fam.FamilleName, YEAR(d.full_date)
),
Pivoted AS (
    SELECT FamilleKey,
           FamilleName,
           SUM(CASE WHEN SalesYear = YEAR(GETDATE()) THEN SalesAmount END) AS SalesCurrentYear,
           SUM(CASE WHEN SalesYear = YEAR(GETDATE()) - 1 THEN SalesAmount END) AS SalesPreviousYear
    FROM SalesByFamily
    GROUP BY FamilleKey, FamilleName
)
SELECT TOP 1
    FamilleName,
    SalesCurrentYear,
    SalesPreviousYear,
    CASE WHEN SalesPreviousYear = 0 THEN NULL
         ELSE (SalesCurrentYear - SalesPreviousYear) * 1.0 / SalesPreviousYear
    END AS GrowthRate
FROM Pivoted
ORDER BY GrowthRate DESC;


Input: Quelle route a le plus progressé en volume de livraison depuis 12 mois ?

Output:
WITH CurrentPeriod AS (
    SELECT dg.Route,
           SUM(fd.QuantiteDelivered) AS volume_current
    FROM FactDelivery fd
    JOIN DimGeography dg ON fd.GeographyKey = dg.GeographyID
    JOIN DimDate dd ON fd.DeliveredDateKey = dd.date_key
    WHERE dd.full_date >= DATEADD(month, -12, CAST(GETDATE() AS date))
      AND dd.full_date <= CAST(GETDATE() AS date)
    GROUP BY dg.Route
),
PreviousPeriod AS (
    SELECT dg.Route,
           SUM(fd.QuantiteDelivered) AS volume_previous
    FROM FactDelivery fd
    JOIN DimGeography dg ON fd.GeographyKey = dg.GeographyID
    JOIN DimDate dd ON fd.DeliveredDateKey = dd.date_key
    WHERE dd.full_date >= DATEADD(month, -24, CAST(GETDATE() AS date))
      AND dd.full_date < DATEADD(month, -12, CAST(GETDATE() AS date))
    GROUP BY dg.Route
)
SELECT TOP 1
    cp.Route,
    cp.volume_current,
    ISNULL(pp.volume_previous, 0) AS volume_previous,
    (cp.volume_current - ISNULL(pp.volume_previous, 0)) AS volume_growth
FROM CurrentPeriod cp
LEFT JOIN PreviousPeriod pp ON cp.Route = pp.Route
ORDER BY volume_growth DESC;


Input: Quels produits qui stagnaient l'an dernier sont devenus des best-sellers cette année ?

Output:
WITH ThisYearSales AS (
    SELECT o.ProductKey,
           p.ProductName,
           SUM(o.AmountAfterDiscount) AS ThisYearAmt
    FROM FactOrders o
    JOIN DimDate d ON o.OrderDateKey = d.date_key
    JOIN DimProduct p ON o.ProductKey = p.ProductKey
    WHERE d.year = YEAR(GETDATE())
    GROUP BY o.ProductKey, p.ProductName
),
LastYearSales AS (
    SELECT o.ProductKey,
           SUM(o.AmountAfterDiscount) AS LastYearAmt
    FROM FactOrders o
    JOIN DimDate d ON o.OrderDateKey = d.date_key
    WHERE d.year = YEAR(DATEADD(year, -1, GETDATE()))
    GROUP BY o.ProductKey
)
SELECT TOP 10
       t.ProductName,
       ISNULL(l.LastYearAmt, 0) AS LastYearAmt,
       t.ThisYearAmt
FROM ThisYearSales t
LEFT JOIN LastYearSales l ON t.ProductKey = l.ProductKey
WHERE ISNULL(l.LastYearAmt, 0) = 0
ORDER BY t.ThisYearAmt DESC;


Input: La Wilaya de Sétif  a-t-elle réalisé un meilleur score ce mois-ci que le mois dernier ?

Output:
WITH MonthlySales AS (
    SELECT
        DD.[year] AS SalesYear,
        DD.[month_num_in_year] AS SalesMonth,
        SUM(FO.[AmountAfterDiscount]) AS TotalCA
    FROM FactOrders FO
    INNER JOIN DimDate DD ON FO.[OrderDateKey] = DD.[date_key]
    INNER JOIN DimCustomer DC ON FO.[CustomerKey] = DC.[CustomerKey]
    WHERE DC.[Wilaya] = N'Sétif'
      AND (
            (DD.[year] = YEAR(GETDATE()) AND DD.[month_num_in_year] = MONTH(GETDATE()))
         OR (DD.[year] = YEAR(DATEADD(month, -1, GETDATE())) AND DD.[month_num_in_year] = MONTH(DATEADD(month, -1, GETDATE())))
          )
    GROUP BY DD.[year], DD.[month_num_in_year]
)
SELECT
    CASE WHEN CUR.TotalCA > PREV.TotalCA THEN N'Oui' ELSE N'Non' END AS IsBetterThisMonth,
    CUR.SalesYear AS CurrentYear,
    CUR.SalesMonth AS CurrentMonth,
    CUR.TotalCA AS CurrentMonthCA,
    PREV.TotalCA AS PreviousMonthCA
FROM MonthlySales CUR
LEFT JOIN MonthlySales PREV
    ON PREV.SalesYear = CASE WHEN CUR.SalesMonth = 1 THEN CUR.SalesYear - 1 ELSE CUR.SalesYear END
   AND PREV.SalesMonth = CASE WHEN CUR.SalesMonth = 1 THEN 12 ELSE CUR.SalesMonth - 1 END
WHERE CUR.SalesYear = YEAR(GETDATE())
  AND CUR.SalesMonth = MONTH(GETDATE());


Input: Quel jour de la semaine a connu la plus forte progression de ventes par rapport à l'an dernier ?

Output:
WITH SalesByDayYear AS (
    SELECT d.day_name,
           YEAR(d.full_date) AS yr,
           SUM(o.AmountAfterDiscount) AS total_sales
    FROM FactOrders o
    JOIN DimDate d ON o.OrderDateKey = d.date_key
    WHERE YEAR(d.full_date) IN (YEAR(GETDATE()), YEAR(GETDATE()) - 1)
    GROUP BY d.day_name, YEAR(d.full_date)
),
Pivoted AS (
    SELECT day_name,
           MAX(CASE WHEN yr = YEAR(GETDATE()) THEN total_sales END) AS sales_current,
           MAX(CASE WHEN yr = YEAR(GETDATE()) - 1 THEN total_sales END) AS sales_prev
    FROM SalesByDayYear
    GROUP BY day_name
),
Growth AS (
    SELECT day_name,
           sales_current,
           sales_prev,
           CASE WHEN sales_prev = 0 THEN NULL
                ELSE (sales_current - sales_prev) * 100.0 / sales_prev END AS pct_growth
    FROM Pivoted
)
SELECT TOP 1
    day_name AS DayOfWeek,
    sales_current AS SalesCurrentYear,
    sales_prev AS SalesPreviousYear,
    pct_growth AS PercentGrowth
FROM Growth
ORDER BY pct_growth DESC;


Input: Quels pré-vendeurs ont un taux de transformation visite/commande supérieur à celui de l'an passé ?

Output:
WITH Visits AS (
    SELECT fv.EmployeeKey, d.[year] AS VisitYear, COUNT(*) AS VisitCount
    FROM FactClientVisits fv
    JOIN DimDate d ON fv.DateKey = d.date_key
    GROUP BY fv.EmployeeKey, d.[year]
),
Orders AS (
    SELECT fo.EmployeeKey, d.[year] AS OrderYear, COUNT(*) AS OrderCount
    FROM FactOrders fo
    JOIN DimDate d ON fo.OrderDateKey = d.date_key
    GROUP BY fo.EmployeeKey, d.[year]
),
Rates AS (
    SELECT
        e.EmployeeKey,
        e.EmployeeID,
        e.EmployeeFullName,
        ISNULL(o_cur.OrderCount, 0) AS OrderCountCur,
        ISNULL(v_cur.VisitCount, 0) AS VisitCountCur,
        CASE WHEN ISNULL(v_cur.VisitCount, 0) = 0 THEN 0
             ELSE CAST(ISNULL(o_cur.OrderCount, 0) AS float) / NULLIF(v_cur.VisitCount, 0)
        END AS RateCurrent,
        ISNULL(o_prev.OrderCount, 0) AS OrderCountPrev,
        ISNULL(v_prev.VisitCount, 0) AS VisitCountPrev,
        CASE WHEN ISNULL(v_prev.VisitCount, 0) = 0 THEN 0
             ELSE CAST(ISNULL(o_prev.OrderCount, 0) AS float) / NULLIF(v_prev.VisitCount, 0)
        END AS RatePrevious
    FROM DimEmployee e
    LEFT JOIN Visits v_cur ON v_cur.EmployeeKey = e.EmployeeKey AND v_cur.VisitYear = YEAR(GETDATE())
    LEFT JOIN Orders o_cur ON o_cur.EmployeeKey = e.EmployeeKey AND o_cur.OrderYear = YEAR(GETDATE())
    LEFT JOIN Visits v_prev ON v_prev.EmployeeKey = e.EmployeeKey AND v_prev.VisitYear = YEAR(GETDATE()) - 1
    LEFT JOIN Orders o_prev ON o_prev.EmployeeKey = e.EmployeeKey AND o_prev.OrderYear = YEAR(GETDATE()) - 1
)
SELECT
    EmployeeID,
    EmployeeFullName,
    RateCurrent,
    RatePrevious
FROM Rates
WHERE RateCurrent > RatePrevious
ORDER BY RateCurrent DESC;


Input: Quelle est la différence de chiffre d'affaires moyen par visite entre ce trimestre et le précédent ?

Output:
DECLARE @CurrentYear smallint = YEAR(GETDATE());
DECLARE @CurrentQuarter tinyint = DATEPART(QUARTER, GETDATE());
DECLARE @PrevDate date = DATEADD(quarter, -1, GETDATE());
DECLARE @PrevYear smallint = YEAR(@PrevDate);
DECLARE @PrevQuarter tinyint = DATEPART(QUARTER, @PrevDate);

WITH VisitRevenue AS (
    SELECT
        fcv.DateKey,
        d.year,
        d.quarter,
        ISNULL(SUM(fo.AmountAfterDiscount), 0) AS Revenue
    FROM FactClientVisits fcv
    LEFT JOIN FactOrders fo
        ON fo.CustomerKey = fcv.CustomerKey
        AND fo.OrderDateKey = fcv.DateKey
    JOIN DimDate d ON d.date_key = fcv.DateKey
    GROUP BY fcv.DateKey, d.year, d.quarter
)
SELECT
    AVG(CASE WHEN year = @CurrentYear AND quarter = @CurrentQuarter THEN Revenue END) -
    AVG(CASE WHEN year = @PrevYear AND quarter = @PrevQuarter THEN Revenue END) AS DiffAvgRevenuePerVisit
FROM VisitRevenue
WHERE (year = @CurrentYear AND quarter = @CurrentQuarter)
   OR (year = @PrevYear AND quarter = @PrevQuarter);


Input: Quelle zone géographique a doublé son nombre de clients en un an ?

Output:
WITH CustomerCounts AS (
    SELECT
        g.Zone,
        d.[year] AS Year,
        COUNT(DISTINCT o.CustomerKey) AS ClientCount
    FROM FactOrders o
    JOIN DimGeography g ON o.GeographyKey = g.GeographyID
    JOIN DimDate d ON o.OrderDateKey = d.date_key
    GROUP BY g.Zone, d.[year]
)
SELECT DISTINCT c.Zone
FROM CustomerCounts c
JOIN CustomerCounts p
    ON c.Zone = p.Zone
   AND c.Year = p.Year + 1
WHERE c.ClientCount >= 2 * p.ClientCount;


Input: Le volume total livré cette semaine est-il supérieur à la moyenne hebdomadaire de l'an passé ?

Output:
WITH CurrentWeek AS (
    SELECT SUM(fd.QuantiteDelivered) AS TotalQty
    FROM FactDelivery fd
    JOIN DimDate dd ON fd.DeliveredDateKey = dd.date_key
    WHERE dd.year = YEAR(GETDATE())
      AND dd.week_num_in_year = dd.week_num_in_year -- current week number
      AND dd.week_num_in_year = DATEPART(week, GETDATE())
),
LastYearWeekly AS (
    SELECT dd.week_num_in_year,
           SUM(fd.QuantiteDelivered) AS WeeklyQty
    FROM FactDelivery fd
    JOIN DimDate dd ON fd.DeliveredDateKey = dd.date_key
    WHERE dd.year = YEAR(GETDATE()) - 1
    GROUP BY dd.week_num_in_year
),
AvgLastYear AS (
    SELECT AVG(WeeklyQty) AS AvgWeeklyQty
    FROM LastYearWeekly
)
SELECT CASE WHEN cw.TotalQty > al.AvgWeeklyQty THEN 1 ELSE 0 END AS IsHigher,
       cw.TotalQty,
       al.AvgWeeklyQty
FROM CurrentWeek cw
CROSS JOIN AvgLastYear al;


Input: Quelle part du chiffre d'affaires de sa catégorie notre produit leader représentait-il cette année par rapport à l'an passé ?

Output:
WITH RevenuePerProduct AS (
    SELECT
        p.ProductKey,
        p.ProductFamily,
        d.[year] AS OrderYear,
        SUM(o.AmountAfterDiscount) AS Revenue
    FROM FactOrders o
    INNER JOIN DimDate d ON o.OrderDateKey = d.date_key
    INNER JOIN DimProduct p ON o.ProductKey = p.ProductKey
    WHERE d.[year] IN (YEAR(GETDATE()), YEAR(GETDATE()) - 1)
    GROUP BY p.ProductKey, p.ProductFamily, d.[year]
),
LeaderPerYear AS (
    SELECT
        OrderYear,
        ProductKey,
        ProductFamily,
        Revenue,
        ROW_NUMBER() OVER (PARTITION BY OrderYear ORDER BY Revenue DESC) AS rn
    FROM RevenuePerProduct
),
CategoryRevenue AS (
    SELECT
        ProductFamily,
        OrderYear,
        SUM(Revenue) AS CategoryRevenue
    FROM RevenuePerProduct
    GROUP BY ProductFamily, OrderYear
)
SELECT
    l.OrderYear AS [Year],
    l.ProductKey,
    p.ProductName AS ProductLeader,
    CAST(100.0 * l.Revenue / c.CategoryRevenue AS decimal(5,2)) AS SharePercent
FROM LeaderPerYear l
INNER JOIN CategoryRevenue c ON l.ProductFamily = c.ProductFamily AND l.OrderYear = c.OrderYear
INNER JOIN DimProduct p ON l.ProductKey = p.ProductKey
WHERE l.rn = 1
ORDER BY l.OrderYear DESC;


Input: Quel est l'écart entre l'objectif de vente de cette année et celui de l'année dernière ?

Output:
SELECT
    SUM(CASE WHEN année = CONVERT(nvarchar(4), YEAR(GETDATE())) THEN Montant ELSE 0 END) -
    SUM(CASE WHEN année = CONVERT(nvarchar(4), YEAR(GETDATE()) - 1) THEN Montant ELSE 0 END) AS EcartMontant
FROM FactObjectifs
WHERE année IN (CONVERT(nvarchar(4), YEAR(GETDATE())), CONVERT(nvarchar(4), YEAR(GETDATE()) - 1));


Input: Quels types de business progressent le plus vite en CA généré cette année ?

Output:
WITH YearlyCA AS (
    SELECT
        dc.BusinessType,
        dd.[year] AS OrderYear,
        SUM(fo.AmountAfterDiscount) AS CA
    FROM FactOrders fo
    INNER JOIN DimDate dd ON fo.OrderDateKey = dd.date_key
    INNER JOIN DimCustomer dc ON fo.CustomerKey = dc.CustomerKey
    WHERE dd.[year] IN (YEAR(GETDATE()), YEAR(GETDATE()) - 1)
    GROUP BY dc.BusinessType, dd.[year]
),
Pivoted AS (
    SELECT
        BusinessType,
        MAX(CASE WHEN OrderYear = YEAR(GETDATE()) THEN CA END) AS CA_CurrentYear,
        MAX(CASE WHEN OrderYear = YEAR(GETDATE()) - 1 THEN CA END) AS CA_PreviousYear
    FROM YearlyCA
    GROUP BY BusinessType
)
SELECT
    BusinessType,
    CA_CurrentYear,
    CA_PreviousYear,
    CASE
        WHEN CA_PreviousYear = 0 OR CA_PreviousYear IS NULL THEN NULL
        ELSE (CA_CurrentYear - CA_PreviousYear) * 100.0 / CA_PreviousYear
    END AS GrowthPct
FROM Pivoted
WHERE CA_CurrentYear IS NOT NULL
ORDER BY GrowthPct DESC;


Input: Quelle famille de notre catalogue a la croissance la plus régulière mois après mois pendant l'année 2025 ?

Output:
WITH MonthlySales AS (
    SELECT
        fam.FamilleKey,
        fam.FamilleName,
        d.month_num_in_year AS MonthNum,
        SUM(o.AmountAfterDiscount) AS MonthlySales
    FROM FactOrders o
    INNER JOIN DimDate d ON o.OrderDateKey = d.date_key
    INNER JOIN DimProduct p ON o.ProductKey = p.ProductKey
    INNER JOIN DimFamille fam ON p.FamilleKey = fam.FamilleKey
    WHERE d.year = 2025
    GROUP BY fam.FamilleKey, fam.FamilleName, d.month_num_in_year
),
Growth AS (
    SELECT
        FamilleKey,
        FamilleName,
        MonthNum,
        MonthlySales,
        LAG(MonthlySales) OVER (PARTITION BY FamilleKey ORDER BY MonthNum) AS PrevSales,
        CASE
            WHEN LAG(MonthlySales) OVER (PARTITION BY FamilleKey ORDER BY MonthNum) = 0 THEN NULL
            ELSE (MonthlySales - LAG(MonthlySales) OVER (PARTITION BY FamilleKey ORDER BY MonthNum)) * 1.0 / LAG(MonthlySales) OVER (PARTITION BY FamilleKey ORDER BY MonthNum)
        END AS GrowthPct
    FROM MonthlySales
),
VarianceCalc AS (
    SELECT
        FamilleKey,
        FamilleName,
        VARP(GrowthPct) AS GrowthVariance,
        COUNT(*) AS MonthsWithGrowth
    FROM Growth
    WHERE GrowthPct IS NOT NULL
    GROUP BY FamilleKey, FamilleName
)
SELECT TOP 1
    FamilleName,
    GrowthVariance
FROM VarianceCalc
ORDER BY GrowthVariance ASC;


Input: Compare le volume de livraison du premier jour du mois actuel avec celui du mois précédent.

Output:
SELECT
    SUM(CASE WHEN d.full_date = DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1) THEN fd.QuantiteDelivered ELSE 0 END) AS VolumeCurrentFirstDay,
    SUM(CASE WHEN d.full_date = DATEFROMPARTS(
            CASE WHEN MONTH(GETDATE()) = 1 THEN YEAR(GETDATE()) - 1 ELSE YEAR(GETDATE()) END,
            CASE WHEN MONTH(GETDATE()) = 1 THEN 12 ELSE MONTH(GETDATE()) - 1 END,
            1) THEN fd.QuantiteDelivered ELSE 0 END) AS VolumePrevFirstDay
FROM FactDelivery fd
JOIN DimDate d ON fd.DeliveredDateKey = d.date_key
WHERE d.full_date IN (
    DATEFROMPARTS(YEAR(GETDATE()), MONTH(GETDATE()), 1),
    DATEFROMPARTS(
        CASE WHEN MONTH(GETDATE()) = 1 THEN YEAR(GETDATE()) - 1 ELSE YEAR(GETDATE()) END,
        CASE WHEN MONTH(GETDATE()) = 1 THEN 12 ELSE MONTH(GETDATE()) - 1 END,
        1)
);


Input: Quels clients commandaient chaque mois l'an dernier mais ne commandent plus qu'une fois par trimestre ?

Output:
WITH LastYearMonthly AS (
    SELECT fo.CustomerKey,
           COUNT(DISTINCT d.month_num_in_year) AS months_cnt
    FROM FactOrders fo
    JOIN DimDate d ON fo.OrderDateKey = d.date_key
    WHERE d.year = YEAR(DATEADD(year, -1, GETDATE()))
    GROUP BY fo.CustomerKey
    HAVING COUNT(DISTINCT d.month_num_in_year) = 12
),
ThisYearQuarterly AS (
    SELECT fo.CustomerKey,
           COUNT(DISTINCT d.quarter) AS quarters_cnt,
           MAX(cnt) AS max_orders_per_quarter,
           SUM(cnt) AS total_orders
    FROM (
        SELECT fo.CustomerKey,
               d.quarter,
               COUNT(*) AS cnt
        FROM FactOrders fo
        JOIN DimDate d ON fo.OrderDateKey = d.date_key
        WHERE d.year = YEAR(GETDATE())
        GROUP BY fo.CustomerKey, d.quarter
    ) q
    JOIN FactOrders fo ON fo.CustomerKey = q.CustomerKey -- just to keep the CustomerKey column
    JOIN DimDate d ON fo.OrderDateKey = d.date_key AND d.year = YEAR(GETDATE())
    GROUP BY fo.CustomerKey
    HAVING MAX(cnt) = 1               -- pas plus d'une commande dans un même trimestre
       AND SUM(cnt) > 0               -- au moins une commande cette année
)
SELECT c.CustomerKey,
       c.CustomerFullName,
       c.CustomerCode,
       c.CustomerReference,
       c.IsActive
FROM DimCustomer c
JOIN LastYearMonthly ly ON c.CustomerKey = ly.CustomerKey
JOIN ThisYearQuarterly ty ON c.CustomerKey = ty.CustomerKey
ORDER BY c.CustomerFullName;


Input: Quelle est la progression du chiffre d'affaires généré par les promotions par rapport à l'an dernier ?

Output:
WITH PromoCA AS (
    SELECT d.[year] AS OrderYear,
           SUM(o.AmountAfterDiscount) AS TotalCA
    FROM FactOrders o
    INNER JOIN DimDate d ON o.OrderDateKey = d.date_key
    LEFT JOIN DimPromotion p ON o.PromotionKey = p.PromotionKey
    WHERE o.PromotionKey IS NOT NULL -- ou o.IsPromo = 1
    GROUP BY d.[year]
)
SELECT cur.OrderYear AS Year,
       cur.TotalCA AS CurrentYearCA,
       prev.TotalCA AS PreviousYearCA,
       CASE WHEN prev.TotalCA = 0 THEN NULL
            ELSE (cur.TotalCA - prev.TotalCA) * 100.0 / prev.TotalCA
       END AS ProgressionPct
FROM PromoCA cur
LEFT JOIN PromoCA prev ON prev.OrderYear = cur.OrderYear - 1
WHERE cur.OrderYear = YEAR(GETDATE());


Input: Le délai de livraison moyen s'est-il amélioré par rapport au trimestre dernier ?

Output:
WITH DeliveryTimes AS (
    SELECT
        fd.GeographyKey,
        od.full_date AS OrderDate,
        dd.full_date AS DeliveredDate,
        DATEDIFF(day, od.full_date, dd.full_date) AS DeliveryDays,
        DATEPART(year, dd.full_date) AS Year,
        DATEPART(quarter, dd.full_date) AS Quarter
    FROM FactDelivery fd
    JOIN DimDate od ON fd.OrderDateKey = od.date_key
    JOIN DimDate dd ON fd.DeliveredDateKey = dd.date_key
    WHERE od.full_date IS NOT NULL
      AND dd.full_date IS NOT NULL
), AvgPerQuarter AS (
    SELECT
        Year,
        Quarter,
        AVG(CAST(DeliveryDays AS float)) AS AvgDeliveryDays
    FROM DeliveryTimes
    WHERE (Year = YEAR(GETDATE()) AND Quarter = DATEPART(quarter, GETDATE()))
       OR (Year = CASE WHEN DATEPART(quarter, GETDATE()) = 1 THEN YEAR(GETDATE())-1 ELSE YEAR(GETDATE()) END
           AND Quarter = CASE WHEN DATEPART(quarter, GETDATE()) = 1 THEN 4 ELSE DATEPART(quarter, GETDATE())-1 END)
    GROUP BY Year, Quarter
)
SELECT
    MAX(CASE WHEN Quarter = DATEPART(quarter, GETDATE()) AND Year = YEAR(GETDATE()) THEN AvgDeliveryDays END) AS CurrentQuarterAvgDays,
    MAX(CASE WHEN Quarter = CASE WHEN DATEPART(quarter, GETDATE()) = 1 THEN 4 ELSE DATEPART(quarter, GETDATE())-1 END
             AND Year = CASE WHEN DATEPART(quarter, GETDATE()) = 1 THEN YEAR(GETDATE())-1 ELSE YEAR(GETDATE()) END
         THEN AvgDeliveryDays END) AS PreviousQuarterAvgDays,
    CASE
        WHEN MAX(CASE WHEN Quarter = DATEPART(quarter, GETDATE()) AND Year = YEAR(GETDATE()) THEN AvgDeliveryDays END) <
             MAX(CASE WHEN Quarter = CASE WHEN DATEPART(quarter, GETDATE()) = 1 THEN 4 ELSE DATEPART(quarter, GETDATE())-1 END
                      AND Year = CASE WHEN DATEPART(quarter, GETDATE()) = 1 THEN YEAR(GETDATE())-1 ELSE YEAR(GETDATE()) END
                  THEN AvgDeliveryDays END)
        THEN 'Improved'
        ELSE 'Not Improved'
    END AS Trend
FROM AvgPerQuarter;


Input: Quelle est la contribution des nouveaux produits (lancés cette année) au CA total ?

Output:
SELECT
    SUM(CASE WHEN YEAR(p.ProductCreationDate) = YEAR(GETDATE()) THEN o.AmountAfterDiscount ELSE 0 END) AS NewProductCA,
    SUM(o.AmountAfterDiscount) AS TotalCA,
    CASE WHEN SUM(o.AmountAfterDiscount) = 0 THEN 0
         ELSE 100.0 * SUM(CASE WHEN YEAR(p.ProductCreationDate) = YEAR(GETDATE()) THEN o.AmountAfterDiscount END) / SUM(o.AmountAfterDiscount)
    END AS ContributionPct
FROM FactOrders AS o
JOIN DimProduct AS p ON o.ProductKey = p.ProductKey;


Input: Quelle région a connu la plus forte chute de commandes par rapport à l'année dernière ?

Output:
WITH OrdersByYear AS (
    SELECT
        g.Region,
        YEAR(d.full_date) AS OrderYear,
        COUNT(DISTINCT o.SalesOrderNum) AS OrderCount
    FROM FactOrders o
    INNER JOIN DimDate d ON o.OrderDateKey = d.date_key
    INNER JOIN DimGeography g ON o.GeographyKey = g.GeographyID
    GROUP BY g.Region, YEAR(d.full_date)
),
CurrentYear AS (
    SELECT Region, OrderCount AS CurrentCount
    FROM OrdersByYear
    WHERE OrderYear = YEAR(GETDATE())
),
PreviousYear AS (
    SELECT Region, OrderCount AS PrevCount
    FROM OrdersByYear
    WHERE OrderYear = YEAR(GETDATE()) - 1
),
Diff AS (
    SELECT
        c.Region,
        c.CurrentCount,
        p.PrevCount,
        (c.CurrentCount - p.PrevCount) AS DiffCount
    FROM CurrentYear c
    INNER JOIN PreviousYear p ON c.Region = p.Region
)
SELECT TOP 1
    Region,
    DiffCount AS OrderDrop
FROM Diff
ORDER BY DiffCount ASC; /* le plus négatif = plus forte chute */


Input: Quels clients ont un Drop Size (DS) qui a doublé en un an ?

Output:
WITH OrderTotals AS (
    SELECT
        o.CustomerKey,
        o.SalesOrderNum,
        SUM(o.AmountAfterDiscount) AS OrderTotal,
        d.[year] AS OrderYear
    FROM FactOrders AS o
    INNER JOIN DimDate AS d ON o.OrderDateKey = d.date_key
    GROUP BY o.CustomerKey, o.SalesOrderNum, d.[year]
),
CustomerYearDropSize AS (
    SELECT
        CustomerKey,
        OrderYear,
        AVG(OrderTotal) AS DropSize
    FROM OrderTotals
    GROUP BY CustomerKey, OrderYear
),
DoublingCustomers AS (
    SELECT
        cPrev.CustomerKey
    FROM CustomerYearDropSize AS cPrev
    INNER JOIN CustomerYearDropSize AS cCurr
        ON cPrev.CustomerKey = cCurr.CustomerKey
        AND cCurr.OrderYear = cPrev.OrderYear + 1
    WHERE cCurr.DropSize >= 2 * cPrev.DropSize
)
SELECT
    dc.CustomerKey,
    dc.CustomerFullName,
    dc.IsActive
FROM DoublingCustomers AS dcIds
INNER JOIN DimCustomer AS dc ON dc.CustomerKey = dcIds.CustomerKey;


Input: Combien de clients n'ont commandé qu'une seule fois l'an dernier et sont devenus réguliers cette année ?

Output:
WITH LastYear AS (
    SELECT FO.CustomerKey,
           COUNT(DISTINCT FO.SalesOrderNum) AS OrderCount
    FROM FactOrders FO
    JOIN DimDate D ON FO.OrderDateKey = D.date_key
    WHERE D.year = YEAR(GETDATE()) - 1
    GROUP BY FO.CustomerKey
),
ThisYear AS (
    SELECT FO.CustomerKey,
           COUNT(DISTINCT FO.SalesOrderNum) AS OrderCount
    FROM FactOrders FO
    JOIN DimDate D ON FO.OrderDateKey = D.date_key
    WHERE D.year = YEAR(GETDATE())
    GROUP BY FO.CustomerKey
)
SELECT COUNT(*) AS ClientCount
FROM LastYear LY
JOIN ThisYear TY ON LY.CustomerKey = TY.CustomerKey
WHERE LY.OrderCount = 1
  AND TY.OrderCount >= 2;


Input: Le taux de couverture des zones rurales a-t-il progressé depuis l'année passée ?

Output:
WITH RuralCustomers AS (
    SELECT DISTINCT c.CustomerKey
    FROM DimCustomer c
    INNER JOIN DimGeography g
        ON c.Route = g.Route
        AND c.Secteur = g.Secteur
        AND c.Zone = g.Zone
        AND c.Region = g.Region
    WHERE g.Zone = 'Rural'
),
OrdersByYear AS (
    SELECT o.CustomerKey, d.year AS OrderYear
    FROM FactOrders o
    INNER JOIN DimDate d ON o.OrderDateKey = d.date_key
    INNER JOIN DimGeography g ON o.GeographyKey = g.GeographyID
    WHERE g.Zone = 'Rural'
)
SELECT
    YEAR(GETDATE()) AS CurrentYear,
    CAST(COUNT(DISTINCT CASE WHEN ob.OrderYear = YEAR(GETDATE()) THEN ob.CustomerKey END) AS float) /
    NULLIF(COUNT(DISTINCT rc.CustomerKey), 0) AS CoverageCurrentYear,
    CAST(COUNT(DISTINCT CASE WHEN ob.OrderYear = YEAR(GETDATE()) - 1 THEN ob.CustomerKey END) AS float) /
    NULLIF(COUNT(DISTINCT rc.CustomerKey), 0) AS CoveragePreviousYear,
    CASE WHEN
        (CAST(COUNT(DISTINCT CASE WHEN ob.OrderYear = YEAR(GETDATE()) THEN ob.CustomerKey END) AS float) /
         NULLIF(COUNT(DISTINCT rc.CustomerKey), 0)) >
        (CAST(COUNT(DISTINCT CASE WHEN ob.OrderYear = YEAR(GETDATE()) - 1 THEN ob.CustomerKey END) AS float) /
         NULLIF(COUNT(DISTINCT rc.CustomerKey), 0))
        THEN 'Oui' ELSE 'Non' END AS TauxProgressé
FROM RuralCustomers rc
LEFT JOIN OrdersByYear ob ON rc.CustomerKey = ob.CustomerKey;


Input: Quelle est l'évolution du chiffre d'affaires le week-end par rapport à l'année dernière ?

Output:
WITH WeekendRevenue AS (
    SELECT
        YEAR(d.full_date) AS [Year],
        SUM(o.AmountAfterDiscount) AS Revenue
    FROM FactOrders o
    JOIN DimDate d ON o.OrderDateKey = d.date_key
    WHERE d.day_name IN ('Saturday', 'Sunday')
      AND YEAR(d.full_date) IN (YEAR(GETDATE()), YEAR(GETDATE()) - 1)
    GROUP BY YEAR(d.full_date)
)
SELECT
    cur.[Year] AS CurrentYear,
    cur.Revenue AS CurrentRevenue,
    prev.Revenue AS PreviousRevenue,
    CASE WHEN prev.Revenue = 0 THEN NULL
         ELSE (cur.Revenue - prev.Revenue) * 100.0 / prev.Revenue
    END AS EvolutionPct
FROM WeekendRevenue cur
LEFT JOIN WeekendRevenue prev ON cur.[Year] = prev.[Year] + 1;


Input: Compare les quantités livrées par Wilaya entre ce trimestre et le même trimestre de l'an dernier.

Output:
SELECT
    DG.Wilaya,
    SUM(CASE WHEN DD.year = YEAR(GETDATE()) AND DD.quarter = DATEPART(QUARTER, GETDATE())
             THEN FD.QuantiteDelivered ELSE 0 END) AS QtyCurrentQuarter,
    SUM(CASE WHEN DD.year = YEAR(GETDATE()) - 1 AND DD.quarter = DATEPART(QUARTER, GETDATE())
             THEN FD.QuantiteDelivered ELSE 0 END) AS QtySameQuarterLastYear
FROM FactDelivery FD
JOIN DimDate DD ON FD.DeliveredDateKey = DD.date_key
JOIN DimGeography DG ON FD.GeographyKey = DG.GeographyID
GROUP BY DG.Wilaya
ORDER BY DG.Wilaya;


Input: Quel est le montant moyen du panier par commande ce mois-ci ?

Output:
WITH OrderTotals AS (
    SELECT
        fo.SalesOrderNum,
        SUM(fo.AmountAfterDiscount) AS OrderTotal
    FROM FactOrders fo
    INNER JOIN DimDate d ON fo.OrderDateKey = d.date_key
    WHERE d.year = YEAR(GETDATE())
      AND d.month_num_in_year = MONTH(GETDATE())
    GROUP BY fo.SalesOrderNum
)
SELECT AVG(OrderTotal) AS AvgBasketAmount
FROM OrderTotals;


Input: Quelle est la quantité moyenne d'articles par commande pour la région Ouest ?

Output:
SELECT AVG(OrderQtyPerOrder) AS AvgQtyPerOrder
FROM (
    SELECT fo.SalesOrderNum,
           SUM(fo.OrderQty) AS OrderQtyPerOrder
    FROM FactOrders fo
    JOIN DimGeography dg ON fo.GeographyKey = dg.GeographyID
    WHERE dg.Region = N'Ouest'
    GROUP BY fo.SalesOrderNum
) AS t;


Input: Quel vendeur a le  Drop Size (panier moyen) en montant le plus élevé aujourd'hui ?

Output:
WITH OrderTotals AS (
    SELECT fo.EmployeeKey,
           fo.SalesOrderNum,
           SUM(fo.AmountAfterDiscount) AS OrderTotal
    FROM FactOrders fo
    JOIN DimDate dd ON fo.OrderDateKey = dd.date_key
    WHERE dd.full_date = CAST(GETDATE() AS date)
    GROUP BY fo.EmployeeKey, fo.SalesOrderNum
)
SELECT TOP 1
       de.EmployeeID,
       de.EmployeeFullName,
       AVG(ot.OrderTotal) AS DropSize
FROM OrderTotals ot
JOIN DimEmployee de ON ot.EmployeeKey = de.EmployeeKey
GROUP BY de.EmployeeID, de.EmployeeFullName
ORDER BY DropSize DESC;


Input: Quel employée a le panier moyen en montant le plus élevé aujourd'hui ?

Output:
WITH OrderTotals AS (
    SELECT
        fo.EmployeeKey,
        fo.SalesOrderNum,
        SUM(fo.AmountAfterDiscount) AS OrderTotal
    FROM FactOrders fo
    INNER JOIN DimDate dd ON fo.OrderDateKey = dd.date_key
    WHERE dd.full_date = CAST(GETDATE() AS DATE) -- aujourd'hui
    GROUP BY fo.EmployeeKey, fo.SalesOrderNum
)
SELECT TOP 1
    de.EmployeeFullName,
    AVG(ot.OrderTotal) AS AvgBasketAmount
FROM OrderTotals ot
INNER JOIN DimEmployee de ON ot.EmployeeKey = de.EmployeeKey
GROUP BY de.EmployeeFullName
ORDER BY AvgBasketAmount DESC;


Input: Comment a évolué le  Drop Size en montant par rapport au mois dernier ?

Output:
;
WITH OrderTotals AS (
    SELECT
        fo.SalesOrderNum,
        SUM(fo.AmountAfterDiscount) AS OrderTotal,
        fo.OrderDateKey
    FROM FactOrders fo
    GROUP BY fo.SalesOrderNum, fo.OrderDateKey
),
MonthlyAvg AS (
    SELECT
        d.year,
        d.month_num_in_year AS month,
        AVG(ot.OrderTotal) AS AvgDropSize
    FROM OrderTotals ot
    JOIN DimDate d ON ot.OrderDateKey = d.date_key
    GROUP BY d.year, d.month_num_in_year
),
CurrentMonth AS (
    SELECT AvgDropSize
    FROM MonthlyAvg
    WHERE year = YEAR(GETDATE()) AND month = MONTH(GETDATE())
),
PreviousMonth AS (
    SELECT AvgDropSize
    FROM MonthlyAvg
    WHERE year = YEAR(DATEADD(month, -1, GETDATE()))
      AND month = MONTH(DATEADD(month, -1, GETDATE()))
)
SELECT
    cm.AvgDropSize AS CurrentMonthDropSize,
    pm.AvgDropSize AS PreviousMonthDropSize,
    (cm.AvgDropSize - pm.AvgDropSize) AS Difference,
    CASE WHEN pm.AvgDropSize = 0 THEN NULL
         ELSE (cm.AvgDropSize - pm.AvgDropSize) / pm.AvgDropSize * 100 END AS PercentChange
FROM CurrentMonth cm
CROSS JOIN PreviousMonth pm;


Input: Quelle est la différence de panier moyen entre les 'Superettes' et les 'Grossistes' ?

Output:
WITH OrderTotals AS (
    SELECT o.SalesOrderNum,
           c.BusinessType,
           SUM(o.AmountAfterDiscount) AS OrderTotal
    FROM FactOrders AS o
    INNER JOIN DimCustomer AS c
        ON o.CustomerKey = c.CustomerKey
    GROUP BY o.SalesOrderNum, c.BusinessType
)
SELECT
    AVG(CASE WHEN BusinessType = 'Superettes' THEN OrderTotal END) -
    AVG(CASE WHEN BusinessType = 'Grossistes' THEN OrderTotal END) AS DifferencePanierMoyen;


Input: Quelle Wilaya affiche le panier moyen en quantité le plus faible ?

Output:
WITH OrderQtyPerOrder AS (
    SELECT
        fo.SalesOrderNum,
        dg.Wilaya,
        SUM(fo.OrderQty) AS QtyPerOrder
    FROM FactOrders fo
    JOIN DimGeography dg ON fo.GeographyKey = dg.GeographyID
    GROUP BY fo.SalesOrderNum, dg.Wilaya
)
SELECT TOP (1)
    Wilaya,
    AVG(QtyPerOrder) AS AvgBasketQty
FROM OrderQtyPerOrder
GROUP BY Wilaya
ORDER BY AvgBasketQty ASC;


Input: Le panier moyen en montant a-t-il augmenté depuis l'année dernière à la même date ?

Output:
WITH OrdersWithDate AS (
    SELECT
        o.SalesOrderNum,
        o.AmountAfterDiscount,
        d.full_date,
        YEAR(d.full_date) AS yr
    FROM FactOrders o
    JOIN DimDate d ON o.OrderDateKey = d.date_key
    WHERE (
        YEAR(d.full_date) = YEAR(GETDATE()) AND d.full_date <= CAST(GETDATE() AS date)
        OR
        YEAR(d.full_date) = YEAR(DATEADD(year, -1, GETDATE())) AND d.full_date <= CAST(DATEADD(year, -1, GETDATE()) AS date)
    )
),
BasketTotals AS (
    SELECT
        SalesOrderNum,
        yr,
        SUM(AmountAfterDiscount) AS BasketTotal
    FROM OrdersWithDate
    GROUP BY SalesOrderNum, yr
),
AvgBasket AS (
    SELECT
        yr,
        AVG(BasketTotal) AS AvgBasketAmount
    FROM BasketTotals
    GROUP BY yr
)
SELECT
    cur.AvgBasketAmount AS AvgBasketCurrentYear,
    prev.AvgBasketAmount AS AvgBasketPreviousYear,
    CASE WHEN cur.AvgBasketAmount > prev.AvgBasketAmount THEN 'Increase' ELSE 'No Increase' END AS Trend
FROM AvgBasket cur
JOIN AvgBasket prev ON cur.yr = YEAR(GETDATE()) AND prev.yr = YEAR(DATEADD(year, -1, GETDATE()));


Input: Quel est le Drop Size des clients qui achètent uniquement la famille Frutty 1,25 L ?

Output:
WITH CustomersOnlyFrutty AS (
    SELECT DISTINCT o.CustomerKey
    FROM FactOrders o
    JOIN DimProduct p ON o.ProductKey = p.ProductKey
    WHERE p.ProductFamily = N'Frutty 1,25 L'
      AND NOT EXISTS (
          SELECT 1
          FROM FactOrders o2
          JOIN DimProduct p2 ON o2.ProductKey = p2.ProductKey
          WHERE o2.CustomerKey = o.CustomerKey
            AND p2.ProductFamily <> N'Frutty 1,25 L'
      )
)
SELECT AVG(OrderTotal) AS DropSize
FROM (
    SELECT o.SalesOrderNum, SUM(o.AmountAfterDiscount) AS OrderTotal
    FROM FactOrders o
    JOIN DimProduct p ON o.ProductKey = p.ProductKey
    JOIN CustomersOnlyFrutty c ON o.CustomerKey = c.CustomerKey
    GROUP BY o.SalesOrderNum
) AS t;


Input: Quels sont les 5 vendeurs dont le Drop Size en quantité a le plus progressé depuis le mois précédent?

Output:
DECLARE @CurrentYear  int = YEAR(GETDATE());
DECLARE @CurrentMonth int = MONTH(GETDATE());
DECLARE @PrevYear  int = CASE WHEN @CurrentMonth = 1 THEN @CurrentYear - 1 ELSE @CurrentYear END;
DECLARE @PrevMonth int = CASE WHEN @CurrentMonth = 1 THEN 12 ELSE @CurrentMonth - 1 END;

-- Drop Size (quantité) pour le mois courant
WITH CurrentDrop AS (
    SELECT
        fo.EmployeeKey,
        AVG(OrderQtyPerOrder) AS DropSizeQty
    FROM (
        SELECT
            fo.EmployeeKey,
            fo.SalesOrderNum,
            SUM(fo.OrderQty) AS OrderQtyPerOrder
        FROM FactOrders fo
        JOIN DimDate dd ON fo.OrderDateKey = dd.date_key
        WHERE dd.[year] = @CurrentYear
          AND dd.month_num_in_year = @CurrentMonth
        GROUP BY fo.EmployeeKey, fo.SalesOrderNum
    ) AS perOrder
    GROUP BY fo.EmployeeKey
),
-- Drop Size (quantité) pour le mois précédent
PrevDrop AS (
    SELECT
        fo.EmployeeKey,
        AVG(OrderQtyPerOrder) AS DropSizeQty
    FROM (
        SELECT
            fo.EmployeeKey,
            fo.SalesOrderNum,
            SUM(fo.OrderQty) AS OrderQtyPerOrder
        FROM FactOrders fo
        JOIN DimDate dd ON fo.OrderDateKey = dd.date_key
        WHERE dd.[year] = @PrevYear
          AND dd.month_num_in_year = @PrevMonth
        GROUP BY fo.EmployeeKey, fo.SalesOrderNum
    ) AS perOrder
    GROUP BY fo.EmployeeKey
)
SELECT TOP 5
    de.EmployeeID AS EmployeeID,
    de.EmployeeFullName AS EmployeeName,
    ISNULL(c.DropSizeQty, 0) AS CurrentDropSizeQty,
    ISNULL(p.DropSizeQty, 0) AS PrevDropSizeQty,
    ISNULL(c.DropSizeQty, 0) - ISNULL(p.DropSizeQty, 0) AS ProgressionQty
FROM DimEmployee de
LEFT JOIN CurrentDrop c ON de.EmployeeKey = c.EmployeeKey
LEFT JOIN PrevDrop p ON de.EmployeeKey = p.EmployeeKey
ORDER BY ProgressionQty DESC;


Input: Quel est le montant moyen d'une commande passée le lundi par rapport au samedi ?

Output:
WITH OrderTotals AS (
    SELECT
        o.SalesOrderNum,
        d.day_name,
        SUM(o.AmountAfterDiscount) AS OrderTotal
    FROM FactOrders o
    JOIN DimDate d ON o.OrderDateKey = d.date_key
    WHERE d.day_name IN ('Monday', 'Saturday')
    GROUP BY o.SalesOrderNum, d.day_name
)
SELECT
    day_name AS Day,
    AVG(OrderTotal) AS AvgOrderAmount
FROM OrderTotals
GROUP BY day_name;


Input: Quelle est la valeur moyenne du panier pour les nouveaux clients créés ce mois-ci ?

Output:
SELECT AVG(OrderTotal) AS AvgBasketValue
FROM (
    SELECT fo.SalesOrderNum,
           SUM(fo.AmountAfterDiscount) AS OrderTotal
    FROM FactOrders fo
    JOIN DimCustomer dc ON fo.CustomerKey = dc.CustomerKey
    WHERE YEAR(dc.FirstOrderDate) = YEAR(GETDATE())
      AND MONTH(dc.FirstOrderDate) = MONTH(GETDATE())
    GROUP BY fo.SalesOrderNum
) AS t;


Input: Quel est le panier moyen en montant pour les produits en promotion ?

Output:
WITH OrderTotals AS (
    SELECT FO.SalesOrderNum,
           SUM(FO.AmountAfterDiscount) AS OrderTotal
    FROM FactOrders FO
    WHERE FO.IsPromo = 1
    GROUP BY FO.SalesOrderNum
)
SELECT AVG(CAST(OrderTotal AS decimal(18,2))) AS PanierMoyenMontant
FROM OrderTotals;


Input: Quelle famille de produits contribue le plus à l'augmentation du panier moyen ?

Output:
SELECT TOP 1
    dp.ProductFamily,
    SUM(fo.AmountAfterDiscount) AS TotalAmountAfterDiscount,
    SUM(fo.AmountAfterDiscount) / NULLIF(COUNT(DISTINCT fo.SalesOrderNum), 0) AS AvgContributionPerOrder
FROM FactOrders AS fo
JOIN DimProduct AS dp ON fo.ProductKey = dp.ProductKey
GROUP BY dp.ProductFamily
ORDER BY TotalAmountAfterDiscount DESC;


Input: Quels clients ont un panier moyen supérieur à 100 000 DA cette année ?

Output:
WITH OrderTotals AS (
    SELECT
        fo.CustomerKey,
        fo.SalesOrderNum,
        SUM(fo.AmountAfterDiscount) AS OrderTotal
    FROM FactOrders fo
    JOIN DimDate dd ON fo.OrderDateKey = dd.date_key
    WHERE dd.year = YEAR(GETDATE())
    GROUP BY fo.CustomerKey, fo.SalesOrderNum
),
ClientAvg AS (
    SELECT
        ot.CustomerKey,
        AVG(ot.OrderTotal) AS AvgBasket
    FROM OrderTotals ot
    GROUP BY ot.CustomerKey
    HAVING AVG(ot.OrderTotal) > 100000
)
SELECT
    c.CustomerKey,
    c.CustomerFullName,
    ca.AvgBasket
FROM ClientAvg ca
JOIN DimCustomer c ON ca.CustomerKey = c.CustomerKey
ORDER BY ca.AvgBasket DESC;


Input: Quelle est la quantité moyenne livrée par commande pour la Wilaya de Béjaïa ?

Output:
WITH OrderQty AS (
    SELECT
        fd.MouvementNumber AS OrderNum,
        SUM(fd.QuantiteDelivered) AS TotalQty
    FROM FactDelivery fd
    INNER JOIN DimGeography dg ON fd.GeographyKey = dg.GeographyID
    WHERE dg.Wilaya = N'Béjaïa'
    GROUP BY fd.MouvementNumber
)
SELECT AVG(CAST(TotalQty AS float)) AS AvgDeliveredQtyPerOrder
FROM OrderQty;


Input: Quel est l'écart de panier moyen entre la région Est et la région Centre ?

Output:
WITH OrderTotals AS (
    SELECT g.Region,
           fo.SalesOrderNum,
           SUM(fo.AmountAfterDiscount) AS OrderTotal
    FROM FactOrders fo
    JOIN DimGeography g ON fo.GeographyKey = g.GeographyID
    WHERE g.Region IN ('Est', 'Centre')
    GROUP BY g.Region, fo.SalesOrderNum
),
RegionAvg AS (
    SELECT Region,
           AVG(OrderTotal) AS AvgBasket
    FROM OrderTotals
    GROUP BY Region
)
SELECT
    MAX(CASE WHEN Region = 'Est' THEN AvgBasket END) -
    MAX(CASE WHEN Region = 'Centre' THEN AvgBasket END) AS BasketAvgDifference
FROM RegionAvg;


Input: Quel est le nombre moyen de livraison par région hier ?

Output:
WITH DeliveriesYesterday AS (
    SELECT dg.Region, fd.GeographyKey
    FROM FactDelivery fd
    INNER JOIN DimGeography dg ON fd.GeographyKey = dg.GeographyID
    INNER JOIN DimDate dd ON fd.DeliveredDateKey = dd.date_key
    WHERE dd.full_date = CAST(DATEADD(day, -1, GETDATE()) AS date)
)
SELECT AVG(CAST(DeliveryCount AS float)) AS AvgDeliveriesPerRegion
FROM (
    SELECT dg.Region, COUNT(*) AS DeliveryCount
    FROM FactDelivery fd
    INNER JOIN DimGeography dg ON fd.GeographyKey = dg.GeographyID
    INNER JOIN DimDate dd ON fd.DeliveredDateKey = dd.date_key
    WHERE dd.full_date = CAST(DATEADD(day, -1, GETDATE()) AS date)
    GROUP BY dg.Region
) AS d;


Input: Quels vendeurs ont un Drop Size en quantité inférieur à la moyenne générale ?

Output:
WITH OrderQtyPerOrder AS (
    SELECT SalesOrderNum,
           EmployeeKey,
           SUM(OrderQty) AS TotalQty
    FROM FactOrders
    GROUP BY SalesOrderNum, EmployeeKey
),
OverallAvg AS (
    SELECT AVG(TotalQty) AS AvgQty
    FROM OrderQtyPerOrder
),
EmployeeAvg AS (
    SELECT EmployeeKey,
           AVG(TotalQty) AS AvgQtyPerEmp
    FROM OrderQtyPerOrder
    GROUP BY EmployeeKey
)
SELECT e.EmployeeID,
       e.EmployeeFullName,
       ea.AvgQtyPerEmp AS DropSizeQuantityAvg
FROM EmployeeAvg ea
JOIN DimEmployee e ON e.EmployeeKey = ea.EmployeeKey
CROSS JOIN OverallAvg oa
WHERE ea.AvgQtyPerEmp < oa.AvgQty
ORDER BY ea.AvgQtyPerEmp ASC;


Input: Quel est le Drop Size (panier moyen) par BusinessType dans la zone Ouest ?

Output:
WITH OrderTotals AS (
    SELECT
        dc.BusinessType,
        fo.SalesOrderNum,
        SUM(fo.AmountAfterDiscount) AS OrderTotal
    FROM FactOrders fo
    INNER JOIN DimCustomer dc ON fo.CustomerKey = dc.CustomerKey
    INNER JOIN DimGeography dg ON fo.GeographyKey = dg.GeographyID
    WHERE dg.Zone = N'Ouest'
    GROUP BY dc.BusinessType, fo.SalesOrderNum
)
SELECT
    BusinessType,
    AVG(OrderTotal) AS DropSize
FROM OrderTotals
GROUP BY BusinessType
ORDER BY DropSize DESC;


Input: Quel est le top 10 des clients ayant la plus grosse valeur moyenne de commande ?

Output:
WITH OrderTotals AS (
    SELECT
        CustomerKey,
        SalesOrderNum,
        SUM(AmountAfterDiscount) AS OrderTotal
    FROM FactOrders
    GROUP BY CustomerKey, SalesOrderNum
),
AvgOrderValue AS (
    SELECT
        CustomerKey,
        AVG(OrderTotal) AS AvgOrderValue
    FROM OrderTotals
    GROUP BY CustomerKey
)
SELECT TOP (10)
    dc.CustomerKey,
    dc.CustomerFullName,
    aov.AvgOrderValue
FROM AvgOrderValue aov
JOIN DimCustomer dc ON aov.CustomerKey = dc.CustomerKey
ORDER BY aov.AvgOrderValue DESC;


Input: Quelle est la quantité moyenne par commande pour les 10 produits les plus vendus ?

Output:
WITH TopProducts AS (
    SELECT TOP (10) ProductKey
    FROM FactOrders
    GROUP BY ProductKey
    ORDER BY SUM(AmountAfterDiscount) DESC
)
SELECT CAST(SUM(o.OrderQty) AS float) / NULLIF(COUNT(DISTINCT o.SalesOrderNum), 0) AS AvgQuantityPerOrder
FROM FactOrders o
JOIN TopProducts tp ON o.ProductKey = tp.ProductKey;


Input: Quelle route a vu son panier moyen en montant doubler depuis janvier ?

Output:
WITH OrderTotals AS (
    SELECT
        fo.SalesOrderNum,
        fo.GeographyKey,
        fo.OrderDateKey,
        SUM(fo.AmountAfterDiscount) AS OrderTotal
    FROM FactOrders fo
    GROUP BY fo.SalesOrderNum, fo.GeographyKey, fo.OrderDateKey
),
JanAvg AS (
    SELECT
        dg.Route,
        AVG(ot.OrderTotal) AS AvgJan
    FROM OrderTotals ot
    JOIN DimDate dd ON ot.OrderDateKey = dd.date_key
    JOIN DimGeography dg ON ot.GeographyKey = dg.GeographyID
    WHERE dd.year = YEAR(GETDATE())
      AND dd.month_num_in_year = 1
    GROUP BY dg.Route
),
PostJanAvg AS (
    SELECT
        dg.Route,
        AVG(ot.OrderTotal) AS AvgPostJan
    FROM OrderTotals ot
    JOIN DimDate dd ON ot.OrderDateKey = dd.date_key
    JOIN DimGeography dg ON ot.GeographyKey = dg.GeographyID
    WHERE dd.year = YEAR(GETDATE())
      AND dd.month_num_in_year > 1
    GROUP BY dg.Route
)
SELECT
    pj.Route,
    pj.AvgPostJan,
    j.AvgJan,
    pj.AvgPostJan / NULLIF(j.AvgJan,0) AS Ratio
FROM PostJanAvg pj
JOIN JanAvg j ON pj.Route = j.Route
WHERE pj.AvgPostJan >= 2 * j.AvgJan;


Input: Le panier moyen des clients 'Gold' est-il vraiment supérieur à celui des 'Silver' durant l'année 2026 ?

Output:
WITH OrderTotals AS (
    SELECT
        o.SalesOrderNum,
        c.BusinessClass,
        SUM(o.AmountAfterDiscount) AS OrderTotal
    FROM FactOrders AS o
    INNER JOIN DimCustomer AS c ON o.CustomerKey = c.CustomerKey
    INNER JOIN DimDate AS d ON o.OrderDateKey = d.date_key
    WHERE d.year = 2026
      AND c.BusinessClass IN ('Gold', 'Silver')
    GROUP BY o.SalesOrderNum, c.BusinessClass
)
SELECT
    BusinessClass,
    AVG(OrderTotal) AS AvgBasket
FROM OrderTotals
GROUP BY BusinessClass
ORDER BY AvgBasket DESC;


Input: Combien de commandes dépassent la moyenne du panier de plus de 50% ?

Output:
WITH OrderTotals AS (
    SELECT SalesOrderNum,
           SUM(AmountAfterDiscount) AS OrderTotal
    FROM FactOrders
    GROUP BY SalesOrderNum
),
AvgTotal AS (
    SELECT AVG(OrderTotal) AS AvgOrderTotal
    FROM OrderTotals
)
SELECT COUNT(*) AS OrdersAboveThreshold
FROM OrderTotals ot
CROSS JOIN AvgTotal a
WHERE ot.OrderTotal > a.AvgOrderTotal * 1.5;


Input: Quel est le montant moyen de commande pour les clients n'ayant pas commandé depuis 30 jours ?

Output:
WITH InactiveCustomers AS (
    SELECT CustomerKey
    FROM DimCustomer
    WHERE DATEDIFF(day, LastOrderDate, GETDATE()) > 30
)
SELECT AVG(OrderTotal) AS AvgOrderAmount
FROM (
    SELECT fo.SalesOrderNum, SUM(fo.AmountAfterDiscount) AS OrderTotal
    FROM FactOrders fo
    INNER JOIN InactiveCustomers ic ON fo.CustomerKey = ic.CustomerKey
    GROUP BY fo.SalesOrderNum
) AS OrderTotals;


Input: Quel est le panier moyen par secteur géographique ?

Output:
WITH OrderTotals AS (
    SELECT
        fo.SalesOrderNum,
        g.Secteur,
        SUM(fo.AmountAfterDiscount) AS OrderTotal
    FROM FactOrders fo
    JOIN DimGeography g ON fo.GeographyKey = g.GeographyID
    GROUP BY fo.SalesOrderNum, g.Secteur
)
SELECT
    Secteur,
    AVG(OrderTotal) AS PanierMoyen
FROM OrderTotals
GROUP BY Secteur
ORDER BY PanierMoyen DESC;


Input: Combien d'articles différents un client achète-t-il en moyenne par visite ?

Output:
WITH VisitProductCounts AS (
    SELECT
        fv.CustomerKey,
        fv.DateKey,
        fv.TimeKey,
        COUNT(DISTINCT fo.ProductKey) AS DistinctProductCount
    FROM FactClientVisits AS fv
    INNER JOIN FactOrders AS fo
        ON fv.CustomerKey = fo.CustomerKey
        AND fv.DateKey = fo.OrderDateKey
    GROUP BY fv.CustomerKey, fv.DateKey, fv.TimeKey
)
SELECT AVG(CAST(DistinctProductCount AS float)) AS AvgDistinctArticlesPerVisit
FROM VisitProductCounts;


Input: Quelle est l'évolution mensuelle de la quantité moyenne par commande en 2026 ?

Output:
WITH OrderQtyPerOrder AS (
    SELECT
        fo.SalesOrderNum,
        d.year,
        d.month_num_in_year AS month_num,
        d.month_name AS month_name,
        SUM(fo.OrderQty) AS TotalQty
    FROM FactOrders fo
    INNER JOIN DimDate d ON fo.OrderDateKey = d.date_key
    WHERE d.year = 2026
    GROUP BY fo.SalesOrderNum, d.year, d.month_num_in_year, d.month_name
)
SELECT
    month_num AS MonthNumber,
    month_name AS MonthName,
    AVG(TotalQty) AS AvgQuantityPerOrder
FROM OrderQtyPerOrder
GROUP BY month_num, month_name
ORDER BY month_num;


Input: Quelle est la valeur moyenne des commandes par jour ouvré ce trimestre ?

Output:
WITH DailyTotals AS (
    SELECT d.full_date,
           SUM(o.AmountAfterDiscount) AS DailyAmount
    FROM FactOrders o
    JOIN DimDate d ON o.OrderDateKey = d.date_key
    WHERE d.year = YEAR(GETDATE())
      AND d.quarter = DATEPART(QUARTER, GETDATE())
      AND d.day_of_week BETWEEN 2 AND 6 -- lundi à vendredi
    GROUP BY d.full_date
)
SELECT AVG(DailyAmount) AS AvgOrderValuePerWorkingDay
FROM DailyTotals;


Input: Combien de clients ont un Drop Size (panier moyen) qui a chuté de plus de 30% ce mois comparant au mois précédent ?

Output:
WITH OrderSums AS (
    SELECT
        fo.CustomerKey,
        fo.SalesOrderNum,
        d.full_date,
        YEAR(d.full_date) AS yr,
        MONTH(d.full_date) AS mo,
        SUM(fo.AmountAfterDiscount) AS OrderTotal
    FROM FactOrders fo
    JOIN DimDate d ON fo.OrderDateKey = d.date_key
    GROUP BY
        fo.CustomerKey,
        fo.SalesOrderNum,
        d.full_date,
        YEAR(d.full_date),
        MONTH(d.full_date)
),
ClientMonthDrop AS (
    SELECT
        CustomerKey,
        yr,
        mo,
        AVG(OrderTotal) AS DropSize
    FROM OrderSums
    GROUP BY CustomerKey, yr, mo
),
CurrentPrev AS (
    SELECT
        c1.CustomerKey,
        c1.DropSize AS DropSizeCurr,
        c2.DropSize AS DropSizePrev,
        c1.yr,
        c1.mo
    FROM ClientMonthDrop c1
    LEFT JOIN ClientMonthDrop c2
        ON c1.CustomerKey = c2.CustomerKey
        AND (
            (c1.yr = c2.yr AND c1.mo = c2.mo + 1)
            OR (c1.yr = c2.yr + 1 AND c1.mo = 1 AND c2.mo = 12)
        )
    WHERE c1.yr = YEAR(GETDATE())
      AND c1.mo = MONTH(GETDATE())
      AND c2.DropSize IS NOT NULL
)
SELECT COUNT(DISTINCT CustomerKey) AS ClientsWithDrop30PctDecrease
FROM CurrentPrev
WHERE DropSizeCurr < DropSizePrev * 0.7;