📊 Data

sql-advanced-analytics

Requêtes SQL avancées pour l'analytique — window functions, CTEs récursives, pivots et optimisation de requêtes complexes.

⚡ Installation & lancement en 1 commande

Copiez-collez dans votre terminal : le skill s'installe dans ~/.claude/skills et Claude Code se lance directement dessus.

macOS / Linux
curl -fsSL https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.sh | sh -s -- sql-advanced-analytics --launch
Windows (PowerShell)
iex "& { $(iwr -useb https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.ps1) } sql-advanced-analytics -Launch"

🚀 Déjà installé ?

claude "/sql-advanced-analytics"

Ou tapez /sql-advanced-analytics dans une session Claude Code, ou décrivez simplement votre besoin — le skill se déclenche automatiquement via le skill-router.

🔑 Déclencheurs automatiques

Le skill s'active automatiquement quand votre demande contient :

window functionCTE récursiverequête analytiquePARTITION BYROW_NUMBERRANKLAGLEADpivot SQL

📦 Installation manuelle

git clone https://github.com/khalilbenaz/claude-skills-collection.git cp -r claude-skills-collection/data-skills/sql-advanced-analytics ~/.claude/skills/

Source : data-skills/sql-advanced-analytics

📖 Manuel

SQL Avancé pour l'Analytique

Workflow

  1. Comprendre le besoin analytique : classement, comparaison temporelle, agrégation cumulative.
  2. Choisir les fonctions : window functions, CTEs, pivots.
  3. Écrire la requête : lisibilité et performance.
  4. Optimiser : plan d'exécution, index, matérialisation.

Window Functions

Classement

-- Classement des produits par ventes dans chaque catégorie
SELECT
    product_name,
    category,
    total_sales,
    ROW_NUMBER() OVER (PARTITION BY category ORDER BY total_sales DESC) AS rank,
    RANK() OVER (PARTITION BY category ORDER BY total_sales DESC) AS rank_with_ties,
    DENSE_RANK() OVER (PARTITION BY category ORDER BY total_sales DESC) AS dense_rank,
    NTILE(4) OVER (PARTITION BY category ORDER BY total_sales DESC) AS quartile
FROM products;

Comparaison temporelle

-- Ventes vs mois précédent + moyenne mobile
SELECT
    month,
    revenue,
    LAG(revenue, 1) OVER (ORDER BY month) AS prev_month,
    revenue - LAG(revenue, 1) OVER (ORDER BY month) AS month_over_month,
    LEAD(revenue, 1) OVER (ORDER BY month) AS next_month,
    AVG(revenue) OVER (ORDER BY month ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg_3m,
    SUM(revenue) OVER (ORDER BY month ROWS UNBOUNDED PRECEDING) AS cumulative_revenue
FROM monthly_sales;

Agrégation avec FIRST_VALUE / LAST_VALUE

-- Premier et dernier achat de chaque client
SELECT DISTINCT
    customer_id,
    FIRST_VALUE(product_name) OVER (
        PARTITION BY customer_id ORDER BY order_date
        ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
    ) AS first_purchase,
    LAST_VALUE(product_name) OVER (
        PARTITION BY customer_id ORDER BY order_date
        ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
    ) AS last_purchase
FROM orders;

CTEs récursives

-- Hiérarchie organisationnelle
WITH RECURSIVE org_tree AS (
    -- Ancre : le CEO
    SELECT id, name, manager_id, 1 AS level, name AS path
    FROM employees
    WHERE manager_id IS NULL

    UNION ALL

    -- Récursion : les subordonnés
    SELECT e.id, e.name, e.manager_id, ot.level + 1,
           ot.path || ' > ' || e.name
    FROM employees e
    JOIN org_tree ot ON e.manager_id = ot.id
)
SELECT * FROM org_tree ORDER BY path;

Pivot / Unpivot

-- Pivot : lignes → colonnes (ventes mensuelles par produit)
SELECT
    product_name,
    SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 1 THEN amount ELSE 0 END) AS jan,
    SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 2 THEN amount ELSE 0 END) AS feb,
    SUM(CASE WHEN EXTRACT(MONTH FROM sale_date) = 3 THEN amount ELSE 0 END) AS mar
FROM sales
GROUP BY product_name;

Optimisation

Index pour les requêtes analytiques

-- Index couvrant pour éviter les lookups
CREATE INDEX idx_sales_analytics
ON sales (category, sale_date)
INCLUDE (amount, product_id);

-- Index partiel pour les requêtes filtrées
CREATE INDEX idx_active_orders
ON orders (customer_id, order_date)
WHERE status = 'active';

Règles