Aller au contenu

Fonctions temporaires & macros

·3 mins·
SQL - Cet article fait partie d'une série.
Partie 3: Cet article

📌 Définitions
#

Fonction SQL
#

Une fonction SQL permet d’encapsuler une logique (calcul, expression, transformation) et de la réutiliser partout dans les requêtes.

Exemples :

  • Nettoyage d’un champ (clean_name(text))
  • Calculs de business (prix_total(qte, prix_unitaire))
  • Formules de scoring

Macro SQL (DBT, BigQuery, DuckDB)
#

Une macro n’est pas une fonction SQL classique.
C’est un bloc de code qui génère du SQL avant exécution.

On peut la voir comme :

Une fonction côté template, qui produit du SQL dynamique. Elle est évaluée avant que la requête ne parte vers la base.

👉 Utile quand on veut écrire du SQL qui écrit du SQL :

  • automations de clauses répétitives
  • génération dynamique de colonnes
  • factorisation de patterns complexes
  • adaptation des requêtes selon les paramètres

Les macros ne s’exécutent donc pas dans la base, mais dans l’outil qui prépare la requête (DBT, BigQuery scripting, DuckDB Python, etc.).

Synthèse
#

Élément Fonction SQL Macro
Où ça s’exécute ? Dans la base Avant l’envoi à la base (template)
Sert à… encapsuler une logique métier générer du SQL dynamique
Exemple prix_total(q, pu) clean_text(col) → génère du SQL
Persistance stockée en base stockée dans le code (dbt / scripts)
Avantages fiabilité, réutilisable flexible, paramétrable, DRY

✅ Exemples de fonctions
#

  • DuckDB / PostgreSQL :

    -- Creation
    CREATE OR REPLACE FUNCTION prix_total(qte INT, prix_unitaire DOUBLE)
    RETURNS DOUBLE AS $$
      SELECT qte * prix_unitaire;
    $$ LANGUAGE SQL;
    
    -- Utilisation
    SELECT prix_total(3, 19.90); -- renvoie 59.7
  • DuckDB (fonction temporaire inline dans Python) :

    import duckdb
    
    duckdb.sql("""
    CREATE FUNCTION prix_total(qte INT, prix DOUBLE)
    RETURNS DOUBLE AS $$
      SELECT qte * prix;
    $$;
    """)
    
    duckdb.sql("SELECT prix_total(2, 5.5)").show()
  • Calcul d’une remise de 10% si commande > 100 €

    -- Creation
    CREATE OR REPLACE FUNCTION prix_avec_remise(montant DOUBLE)
    RETURNS DOUBLE AS $$
      SELECT CASE
        WHEN montant > 100 THEN montant * 0.9
        ELSE montant
      END;
    $$ LANGUAGE SQL;
    
    -- Utilisation
    SELECT commande_id, prix_avec_remise(150) AS prix_final;

✅ Exemples de macro dans DBT
#

  • Normalisation d’une colonne texte (trim, lowercase, retirer accents…).

    -- macros/clean_text.sql
    {% macro clean_text(col) %}
        lower(trim({{ col }}))
    {% endmacro %}

Puis utilisation dans une requête :

SELECT
    {{ clean_text("client_name") }} AS client_clean
FROM clients;

→ Au moment du rendering, DBT remplace la ligne par :

lower(trim(client_name)) AS client_clean

➡️ On ne réécrit pas la transformation à chaque fois. ➡️ Le SQL final exécuté par la base ne contient plus la macro, seulement le code généré.

✅ Exemples de macro dans BigQuery
#

BigQuery n’a pas de macros “DBT”, mais propose des templates via scripting :

CREATE TEMP FUNCTION clean_text(x STRING)
RETURNS STRING AS (
  LOWER(TRIM(x))
);

SELECT clean_text(client_name) FROM clients;

Différence importante : ici, c’est une vraie fonction exécutée dans BigQuery, pas du templating.


🧯 Pièges à éviter
#

⚠️ Problème ✅ Solution
Type de retour mal défini Toujours déclarer RETURNS type
SQL dynamique dans une fonction → erreur Ne pas inclure de requêtes dynamiques (cf. procédures PL/pgSQL)
Réutilisation trop complexe Favoriser les CTEs si fonction trop spécifique

🏋️‍♂️ Exercices
#

  • Créer une fonction nettoie_nom(text) qui :
    • met en minuscules
    • enlève les espaces
  • Créer une fonction statut_commande(qte INT) qui retourne :
    • ‘grosse commande’ si qte > 10
    • ‘petite commande’ sinon
  • Utilise une fonction dans une requête sur la table commandes.
duckdb.sql("""
CREATE FUNCTION statut_commande(qte INT)
RETURNS TEXT AS $$
  SELECT CASE WHEN qte > 10 THEN 'grosse' ELSE 'petite' END;
$$;

SELECT statut_commande(5), statut_commande(20);
""").df()

📚 8. Ressources utiles
#

Thibault CLEMENT - Intechnia
Auteur
Thibault CLEMENT - Intechnia
Data Scientist / ML Engineer
SQL - Cet article fait partie d'une série.
Partie 3: Cet article