---
title: "Transformations SQL au sein de l'OVHcloud Data Platform"
description: "SQL (Structured Query Language) demeure le langage le plus utilisé et le plus efficace pour interroger et transformer des données structurées"
url: https://docs.ovhcloud.com/fr/guides/public-cloud/data-platform/tutorials-sql-transformation
lang: fr
lastUpdated: 2026-09-14
---
> For AI agents: the complete documentation index is available at https://docs.ovhcloud.com/fr/llms.txt, the full documentation bundle is available at https://docs.ovhcloud.com/fr/llms-full.txt.

# Transformations SQL au sein de l'OVHcloud Data Platform

## Objectif

Bienvenue dans le guide sur les **transformations SQL au sein de l'OVHcloud Data Platform**. SQL (Structured Query Language) demeure le langage le plus utilisé et le plus efficace pour interroger et transformer des données structurées. Ce document vous présente les concepts clés de l'utilisation de SQL pour la manipulation et l'agrégation de données directement au sein de notre platform, en exploitant ses puissantes capacités de traitement des données.

Que vous souhaitiez nettoyer, remodeler, filtrer ou agréger de grands datasets, SQL offre un moyen robuste et intuitif d'atteindre vos objectifs de transformation de données. Sa nature déclarative vous permet de vous concentrer sur ce que vous voulez obtenir avec vos données, plutôt que sur la manière dont les opérations sont exécutées, ce qui le rend accessible à un large éventail de professionnels de la donnée.

## Pourquoi utiliser SQL pour la transformation de données ?

SQL est un outil indispensable dans le pipeline de transformation de données, pour plusieurs raisons clés :

- **Universalité :** c'est un langage standard, largement adopté par diverses bases de données et data platforms, ce qui rend les compétences facilement transférables.
- **Lisibilité et simplicité :** sa syntaxe proche de l'anglais rend les opérations complexes relativement faciles à comprendre et à écrire.
- **Performance :** les moteurs SQL sont hautement optimisés pour les opérations relationnelles, surpassant souvent le code personnalisé pour la manipulation de données à grande échelle.
- **Nature déclarative :** vous spécifiez l'état final souhaité de vos données, et le moteur détermine la manière la plus efficace de l'atteindre.
- **Intégration :** s'intègre parfaitement aux outils d'entreposage de données, de business intelligence et de reporting.

## Concepts clés des transformations SQL

Dans son principe, la transformation SQL consiste à utiliser des commandes SQL standard pour manipuler les données. Cela peut inclure :

### 1. Nettoyage et préparation des données

- **Filtrage :** utilisation des clauses `WHERE` pour sélectionner des lignes spécifiques selon des conditions.
- **Sélection/Projection :** utilisation des instructions `SELECT` pour choisir des colonnes spécifiques et les renommer (`AS`).
- **Conversion de type :** utilisation des fonctions `CAST` ou `TRY_CAST` pour changer les types de données. `TRY_CAST` est particulièrement utile dans Trino pour gérer avec souplesse les erreurs de conversion (en renvoyant `NULL` au lieu de provoquer un plantage).
- **Gestion des valeurs manquantes :** utilisation des instructions `COALESCE` ou `CASE` pour remplacer les valeurs `NULL`.
- **Manipulation de chaînes de caractères :** des fonctions comme `SUBSTRING`, `LENGTH`, `UPPER`, `LOWER`, `TRIM` pour nettoyer et standardiser les données textuelles.

### 2. Agrégation et synthèse des données

- **Regroupement :** utilisation de `GROUP BY` pour agréger les lignes ayant les mêmes valeurs dans des colonnes spécifiées.
- **Fonctions d'agrégation :** application de fonctions comme `COUNT`, `SUM`, `AVG`, `MIN`, `MAX` aux groupes synthétisés.
- **Filtrage des agrégations :** utilisation des clauses `HAVING` pour filtrer les résultats des opérations `GROUP BY`.

### 3. Remodelage et restructuration des données

- **Jointures :** combinaison de données provenant de deux tables ou plus sur la base de colonnes liées (`INNER JOIN`, `LEFT JOIN`, `RIGHT JOIN`, `FULL OUTER JOIN`).
- **Unions :** combinaison des ensembles de résultats de deux instructions `SELECT` ou plus (`UNION`, `UNION ALL`).
- **Pivot/Dépivot :** transformation de lignes en colonnes (pivot) ou de colonnes en lignes (dépivot) pour modifier la structure des données. En SQL Trino (couramment utilisé dans le DPE), le pivot est souvent réalisé à l'aide de `SUM` avec `FILTER` ou d'instructions `CASE`, et le dépivot avec `CROSS JOIN UNNEST`.
- **Fonctions de fenêtrage :** exécution de calculs sur un ensemble de lignes d'une table, liées à la ligne courante, sans regrouper les lignes (`ROW_NUMBER()`, `RANK()`, `LEAD()`, `LAG()`, `SUM() OVER()`, `AVG() OVER()`).

## Transformations SQL sur l'OVHcloud Data Platform (guide pratique)

Cette section fournit un exemple pratique de bout en bout de transformations SQL au sein des Notebooks DPE (Data Processing Environment) de l'OVHcloud Data Platform, en utilisant spécifiquement le SDK et en se concentrant sur le dataset **dirty\_cafe\_sales**.

### Prérequis

1. Téléchargez le fichier <a href="/images/public-cloud/data-platform/getting-further/ai-endpoints/resources/dirty_cafe_sales.csv" download>dirty\_cafe\_sales.csv</a>
2. Chargez-le dans les [Connectors](https://docs.ovhcloud.com/fr/guides/public-cloud/data-platform/landing-page-connectors.md) et extrayez les métadonnées à l'aide de l'[Analyzer](https://docs.ovhcloud.com/fr/guides/public-cloud/data-platform/landing-page-connectors-analyzer.md).
3. Créez une nouvelle [Table](https://docs.ovhcloud.com/fr/guides/public-cloud/data-platform/lakehouse-manager-tables.md) à partir de la source dans le [Lakehouse Manager](https://docs.ovhcloud.com/fr/guides/public-cloud/data-platform/landing-page-lakehouse-manager.md)

**Informations sur le dataset :**

Nous allons travailler avec un dataset simulé de ventes de café nommé `dirty_cafe_sales`. Il contient les colonnes suivantes et les problèmes de qualité de données connus :

| Nom de colonne     | Description                                                       | Problèmes connus                                                                                 |
| :----------------- | :---------------------------------------------------------------- | :----------------------------------------------------------------------------------------------- |
| `transaction_id`   | Identifiant unique de chaque transaction                          | Aucun                                                                                            |
| `item`             | Nom de l'article vendu                                            | Aucun                                                                                            |
| `quantity`         | Nombre d'unités vendues dans la transaction                       | Contient des chaînes 'UNKNOWN'                                                                   |
| `price_per_unit`   | Prix d'une seule unité de l'article                               | Aucun                                                                                            |
| `total_spent`      | Montant total dépensé pour la ligne d'article dans la transaction | Contient des chaînes 'ERROR'                                                                     |
| `payment_method`   | Méthode utilisée pour le paiement (par ex. Credit Card, Cash)     | Aucun                                                                                            |
| `location`         | Lieu de vente (par ex. In-store, Takeaway)                        | Contient des chaînes 'ERROR' et des chaînes vides `''`                                           |
| `transaction_date` | Date de la transaction                                            | Contient des chaînes non-date (par ex. 'ERROR'), nécessite un casting et une gestion des erreurs |

### 1. Créer un nouveau notebook DPE

- Naviguez vers Data Processing Environment (DPE) → Notebooks.
- Cliquez sur **+ New Notebook** et, pour les besoins de ce guide, nous continuerons avec le **Base Notebook**.
- Donnez à votre notebook un nom explicite (par ex. `Cafe_Sales_SQL_Transformations`).
- Cliquez sur **Create**.
- Une fois JupyterLab ouvert, cliquez sur le notebook Python3 pour créer un nouveau fichier `.ipynb`. C'est ici que nous allons exécuter toutes les étapes suivantes dans des cellules.

### 2. Se connecter au SDK

Nous allons utiliser le SDK fourni dans votre environnement DPE. Ce SDK fournit des méthodes pour se connecter au Lakehouse Manager et interagir avec les tables.

```python
# Importer les modules nécessaires depuis le SDK
from forepaas.dwh import connect, bulk_insert
from forepaas.core.settings import CONFIG
from forepaas.dwh.logical import LogicalObject
import pandas as pd #utile pour afficher les dataframes

print("SDK modules imported successfully.")
```

### 3. Lister les tables du dataset

Avant de se connecter à `dirty_cafe_sales`, il est recommandé de lister les tables disponibles pour confirmer sa présence et son nom exact au sein du chemin de données spécifié.

```python
# Se connecter au Lakehouse Manager
# Se connecter au dataset par défaut du Lakehouse Manager
connector = connect("dwh/default_dataset/")

print("Listing tables in 'dwh/default_dataset/':")
available_tables = connector.list()
for table_name in available_tables:
    print(f"- {table_name}")

if "dirty_cafe_sales" in available_tables:
    print("\n'dirty_cafe_sales' table found!")
else:
    print("\nWARNING: 'dirty_cafe_sales' table not found. Please check the table name or path.")
```

### 4. Se connecter à la table et inspecter les données

Maintenant, connectons-nous à la table `dirty_cafe_sales` à l'aide de `connector.select()` et affichons ses informations et ses statistiques descriptives. Cette étape permet de confirmer visuellement les données, y compris les valeurs 'ERROR' et 'UNKNOWN' que nous devons nettoyer.

```python
# Se connecter à la table 'dirty_cafe_sales'
df_raw_sales = connector.select("dirty_cafe_sales")

print("\nDataset information:")
df_raw_sales.info()

print("\nDataset details:")
df_raw_sales.describe()

print("\nSample of Raw Data (first 5 rows):")
display(df_raw_sales.head())
```

### 5. Exécuter des commandes SQL (transformations)

C'est le cœur de notre transformation. Nous allons définir deux requêtes SQL : une simple pour une exploration de base et une plus complexe pour un nettoyage approfondi et une agrégation détaillée.

:::info
**Remarque importante sur les points-virgules :** lorsque vous exécutez du SQL via un SDK ou une API dans un environnement programmatique tel qu'un notebook, **n'incluez pas de point-virgule final (`;`)** à la toute fin de votre chaîne de requête SQL. L'API attend généralement une seule instruction SQL sans délimiteur explicite à la fin. En inclure un peut entraîner des erreurs courantes telles que `mismatched input ';'` ou `syntax error near ';'`.
:::

#### 5.1 Requête SQL simple : total des ventes quotidien par emplacement (exploration initiale)

Cette requête illustre une agrégation basique, montrant d'abord comment les problèmes de données brutes peuvent entraîner des erreurs, puis les corrigeant à l'aide de `TRY_CAST` pour plus de robustesse. Elle nettoie également le champ `location`.

```python
print("--- Running Simple SQL Query ---")

SIMPLE_SQL_QUERY = """
SELECT
    CAST(valid_transaction_date AS DATE) AS sale_date,
    -- Handle 'ERROR' and empty strings in location
    CASE
        WHEN location = 'ERROR' THEN 'Unknown'
        WHEN TRIM(location) = '' THEN 'Unknown'
        ELSE location
    END AS clean_location,
    SUM(TRY_CAST(total_spent AS DOUBLE)) AS gross_revenue_dirty
FROM
    (
        SELECT
            TRY_CAST(transaction_date AS DATE) AS valid_transaction_date,
            location,
            total_spent
        FROM
            dirty_cafe_sales
    ) AS subquery_sales
WHERE
    valid_transaction_date IS NOT NULL
GROUP BY
    CAST(valid_transaction_date AS DATE),
    CASE
        WHEN location = 'ERROR' THEN 'Unknown'
        WHEN TRIM(location) = '' THEN 'Unknown'
        ELSE location
    END
ORDER BY
    sale_date DESC, clean_location
""" # No semicolon at the end here!

try:
    # Execute the query using your connector's method.
    df_simple_result = connector.query(SIMPLE_SQL_QUERY)
    
    # --- Pandas Post-Processing for Data Types ---
    # Convert 'sale_date' to datetime objects for proper date operations
    df_simple_result['sale_date'] = pd.to_datetime(df_simple_result['sale_date'])
    # --- End Pandas Post-Processing ---

    print("\nSimple Query Results (first 10 rows):")
    display(df_simple_result.head(10))
    print("\nSimple Query Results Schema:")
    df_simple_result.info()

except Exception as e:
    print(f"Error executing Simple SQL query: {e}")
    print("\nFailed SQL Query:\n", SIMPLE_SQL_QUERY)
```

#### 5.2 Requête SQL complexe : performance quotidienne détaillée et nettoyée par article

Cette requête effectue un nettoyage de données robuste, calcule des métriques de vente précises, et les agrège par date, article et emplacement. Elle traite directement les problèmes de qualité de données identifiés (`UNKNOWN` dans `quantity`, `ERROR` dans `total_spent`, chaînes `transaction_date` invalides, et entrées `location` problématiques).

```python
print("\n--- Running Complex SQL Transformation Query ---")

COMPLEX_SQL_TRANSFORMATION_QUERY = """
WITH cleaned_and_corrected_sales AS (
    SELECT
        transaction_id,
        item,
        -- Clean and cast quantity: 'UNKNOWN' becomes NULL, then cast to INTEGER.
        -- TRY_CAST handles non-numeric strings safely by returning NULL.
        TRY_CAST(NULLIF(quantity, 'UNKNOWN') AS INTEGER) AS quantity_cleaned,
        -- Ensure price_per_unit is numeric, handling potential non-numeric entries safely.
        TRY_CAST(price_per_unit AS DOUBLE) AS price_per_unit_cleaned,
        payment_method,
        -- Clean location: 'ERROR' and empty strings become 'Unknown'.
        CASE
            WHEN location = 'ERROR' THEN 'Unknown'
            WHEN TRIM(location) = '' THEN 'Unknown'
            ELSE location
        END AS clean_location,
        -- Use TRY_CAST for transaction_date to handle bad date strings safely, then filter later.
        TRY_CAST(transaction_date AS DATE) AS sale_date_raw
    FROM
        dirty_cafe_sales
),
final_calculated_sales AS (
    SELECT
        transaction_id,
        item,
        quantity_cleaned AS final_quantity,
        price_per_unit_cleaned AS final_price_per_unit,
        -- Recalculate total_spent based on cleaned quantity and price_per_unit.
        quantity_cleaned * price_per_unit_cleaned AS calculated_total_spent,
        payment_method,
        clean_location,
        sale_date_raw AS sale_date
    FROM
        cleaned_and_corrected_sales
    -- Filter out rows where crucial values (quantity, price_per_unit, or sale_date)
    -- couldn't be cleanly converted, ensuring only valid data proceeds.
    WHERE
        quantity_cleaned IS NOT NULL 
        AND price_per_unit_cleaned IS NOT NULL
        AND sale_date_raw IS NOT NULL 
)
SELECT
    sale_date,
    item,
    clean_location AS location,
    COUNT(DISTINCT transaction_id) AS number_of_transactions,
    SUM(final_quantity) AS total_items_sold,
    SUM(calculated_total_spent) AS total_revenue_cleaned,
    AVG(final_price_per_unit) AS average_item_price_per_unit,
    -- Pivot revenue by payment method using Trino's FILTER clause
    SUM(calculated_total_spent) FILTER (WHERE payment_method = 'Credit Card') AS revenue_credit_card,
    SUM(calculated_total_spent) FILTER (WHERE payment_method = 'Cash') AS revenue_cash,
    SUM(calculated_total_spent) FILTER (WHERE payment_method = 'Digital Wallet') AS revenue_digital_wallet,
    -- Calculate average quantity per transaction for this group
    CAST(SUM(final_quantity) AS DOUBLE) / CAST(COUNT(DISTINCT transaction_id) AS DOUBLE) AS avg_quantity_per_transaction
FROM
    final_calculated_sales
GROUP BY
    sale_date,
    item,
    clean_location
ORDER BY
    sale_date DESC, total_revenue_cleaned DESC
""" # No semicolon at the end here!

try:
    # Execute the complex transformation query
    df_transformed = connector.query(COMPLEX_SQL_TRANSFORMATION_QUERY)

    # --- Pandas Post-Processing for Data Types ---
    # Convert 'sale_date' to datetime objects for proper date operations
    df_transformed['sale_date'] = pd.to_datetime(df_transformed['sale_date'])
    # --- End Pandas Post-Processing ---

    print("\nTransformed Cafe Sales Data (Sample - first 5 rows):")
    display(df_transformed.head())
    print(f"\nTransformed Data Schema:")
    df_transformed.info()

    print(f"\nTotal rows in transformed data: {len(df_transformed)}")

except Exception as e:
    print(f"Error during Complex SQL transformation: {e}")
    print("\nFailed SQL Query:\n", COMPLEX_SQL_TRANSFORMATION_QUERY)
```

### 6. Créer une table physique à partir des données transformées (CTAS)

Après avoir réalisé avec succès la transformation complexe et vérifié les résultats, l'étape logique suivante consiste à persister ces données nettoyées et agrégées dans une nouvelle table physique de votre base de données. Cela se fait généralement à l'aide d'une instruction `CREATE TABLE AS SELECT` (CTAS). Cette nouvelle table peut ensuite être utilisée pour le reporting, des analyses supplémentaires, ou comme source pour d'autres traitements de données, sans avoir besoin de réexécuter la logique de nettoyage complexe à chaque fois.

:::info
**Remarque importante sur l'exécution SQL :** certains connecteurs ou API de base de données n'attendent qu'une seule instruction SQL par appel `query()`. Pour exécuter `DROP TABLE` et `CREATE TABLE AS SELECT`, nous les enverrons sous forme de commandes séparées. Assurez-vous également qu'il n'y a pas de points-virgules finaux à la toute fin de chaque chaîne de requête.
:::

```python
print("\n--- Creating Physical Table from Complex SQL Transformation Query ---")

# Define the name of your new cleaned table. This variable can be reused across cells.
NEW_CLEANED_TABLE_NAME = "cleaned_cafe_sales_daily_summary"

# 1. DROP TABLE statement (removes the table if it already exists, for idempotent runs)
# Note: No trailing semicolon at the very end of the string.
DROP_TABLE_QUERY = f"DROP TABLE IF EXISTS {NEW_CLEANED_TABLE_NAME}"

# 2. CREATE TABLE AS SELECT statement
# This uses the same logic from the COMPLEX_SQL_TRANSFORMATION_QUERY
# Note: No trailing semicolon at the very end of the string.
CTAS_CORE_QUERY = f"""
CREATE TABLE {NEW_CLEANED_TABLE_NAME} AS
WITH cleaned_and_corrected_sales AS (
    SELECT
        transaction_id,
        item,
        TRY_CAST(NULLIF(quantity, 'UNKNOWN') AS INTEGER) AS quantity_cleaned,
        TRY_CAST(price_per_unit AS DOUBLE) AS price_per_unit_cleaned,
        payment_method,
        CASE
            WHEN location = 'ERROR' THEN 'Unknown'
            WHEN TRIM(location) = '' THEN 'Unknown'
            ELSE location
        END AS clean_location,
        TRY_CAST(transaction_date AS DATE) AS sale_date_raw
    FROM
        dirty_cafe_sales
),
final_calculated_sales AS (
    SELECT
        transaction_id,
        item,
        quantity_cleaned AS final_quantity,
        price_per_unit_cleaned AS final_price_per_unit,
        quantity_cleaned * price_per_unit_cleaned AS calculated_total_spent,
        payment_method,
        clean_location,
        sale_date_raw AS sale_date
    FROM
        cleaned_and_corrected_sales
    WHERE
        quantity_cleaned IS NOT NULL 
        AND price_per_unit_cleaned IS NOT NULL
        AND sale_date_raw IS NOT NULL 
)
SELECT
    sale_date,
    item,
    clean_location AS location,
    COUNT(DISTINCT transaction_id) AS number_of_transactions,
    SUM(final_quantity) AS total_items_sold,
    SUM(calculated_total_spent) AS total_revenue_cleaned,
    AVG(final_price_per_unit) AS average_item_price_per_unit,
    SUM(calculated_total_spent) FILTER (WHERE payment_method = 'Credit Card') AS revenue_credit_card,
    SUM(calculated_total_spent) FILTER (WHERE payment_method = 'Cash') AS revenue_cash,
    SUM(calculated_total_spent) FILTER (WHERE payment_method = 'Digital Wallet') AS revenue_digital_wallet,
    CAST(SUM(final_quantity) AS DOUBLE) / CAST(COUNT(DISTINCT transaction_id) AS DOUBLE) AS avg_quantity_per_transaction
FROM
    final_calculated_sales
GROUP BY
    sale_date,
    item,
    clean_location
ORDER BY
    sale_date DESC, total_revenue_cleaned DESC
"""

try:
    # Execute DROP TABLE first
    print(f"Dropping table {NEW_CLEANED_TABLE_NAME} if it exists...")
    connector.query(DROP_TABLE_QUERY)
    print("Drop table command executed.")

    # Then execute CREATE TABLE AS SELECT
    print(f"Creating table {NEW_CLEANED_TABLE_NAME}...")
    # For DDL operations like CREATE TABLE, connector.query() might return an empty DataFrame or None.
    connector.query(CTAS_CORE_QUERY)
    
    print(f"\nSuccessfully created table: {NEW_CLEANED_TABLE_NAME}")
    
    # Optional: Verify the table was created by querying its schema or a few rows
    print(f"\nVerifying schema of new table: {NEW_CLEANED_TABLE_NAME}")
    df_verify = connector.query(f"SELECT * FROM {NEW_CLEANED_TABLE_NAME} LIMIT 5")
    display(df_verify)
    df_verify.info()

except Exception as e:
    print(f"Error during CTAS operation for {NEW_CLEANED_TABLE_NAME}: {e}")
    if "DROP TABLE" in str(e) and DROP_TABLE_QUERY in str(e):
        print("\nFailed SQL Query (DROP TABLE):\n", DROP_TABLE_QUERY)
    elif "CREATE TABLE" in str(e) and CTAS_CORE_QUERY in str(e):
        print("\nFailed SQL Query (CREATE TABLE AS SELECT):\n", CTAS_CORE_QUERY)
    else:
        print("\nFailed SQL Query:\n", e)
```

### 7. Explorer la nouvelle table physique

Vous pouvez utiliser des commandes de métadonnées SQL standard pour explorer votre table physique nouvellement créée. N'oubliez pas de remplacer `<your_catalog_name>` et `<your_schema_name>` par vos valeurs réelles.

```python
# You'll need to know your catalog and schema names.
# Example: your_catalog_name = "default_dataset", your_schema_name = "sales_data"
# To retrieve catalog and schema name you can execute the following commands in the Lakehouse Manager Explorer
# CATALOG LIST: show catalogs
# SCHEMA LIST: show schemas from {catalog_name}

your_catalog_name = "your_main_catalog" # <<< IMPORTANT: Replace with your actual catalog name!
your_schema_name = "your_schema_name"   # <<< IMPORTANT: Replace with your actual schema name!
your_table_name = "cleaned_cafe_sales_daily_summary"

print(f"\n--- Exploring the New Table: {your_table_name} ---")

try:
    # Describe your new table
    df_describe = connector.query(f"DESCRIBE {your_catalog_name}.{your_schema_name}.{your_table_name}")
    print(f"\nDescription of table '{your_table_name}':")
    display(df_describe)
    
    # Select some data from your new table
    df_sample_data = connector.query(f"SELECT * FROM {your_catalog_name}.{your_schema_name}.{your_table_name} LIMIT 5")
    print(f"\nSample data from '{your_table_name}':")
    display(df_sample_data)

except Exception as e:
    print(f"Error exploring table '{your_table_name}': {e}")
    print("Please check the full table path (catalog.schema.table) and permissions.")
```

### 8. Créer un objet logique à partir de la table physique

Lorsque vous créez une nouvelle table via SQL, elle n'existe qu'en tant que table physique dans la base de données. Cependant, la section Tables de l'interface fonctionne à un niveau logique. Elle affiche les tables enregistrées comme des objets logiques au sein de la platform.

Pour rendre votre table physique nouvellement créée visible et utilisable dans l'interface, vous devez créer un objet logique correspondant. Cette représentation logique agit comme un pont entre la base de données et l'interface de la platform, vous permettant d'interagir avec le schéma et les données de la table directement depuis l'interface.

```python
print(f"\n--- Creating LogicalObject for '{NEW_CLEANED_TABLE_NAME}' ---")

try:
        
    logical_cleaned_sales = LogicalObject().create_from_physical(NEW_CLEANED_TABLE_NAME)
    print(f"Successfully created logical object for: {NEW_CLEANED_TABLE_NAME}")

except NameError:
    print("Error: 'LogicalObject' is not defined. Please ensure you have imported the correct library/class or that it's globally accessible.")
except Exception as e:
    print(f"Error creating logical object: {e}")
```

:::info
Si vous souhaitez supprimer un LogicalObject que vous avez créé, vous pouvez directement supprimer la table depuis l'interface, ou bien utiliser la méthode - `LogicalObject().remove("table_name")` - qui supprimera la table à la fois au niveau logique et physique.
:::

### Conclusion

Vous avez parcouru avec succès un processus de transformation SQL de bout en bout sur l'OVHcloud Data Platform. En partant d'un dataset brut et non nettoyé, vous avez appliqué diverses techniques SQL de nettoyage, d'agrégation et de remodelage pour produire un dataset propre, synthétisé et hautement utilisable. Ces données transformées ont ensuite été persistées dans une nouvelle table physique et représentées comme un objet logique pour une intégration fluide dans vos workflows Python. Ces connaissances fondamentales vous permettent d'aborder des défis de préparation de données plus complexes et de construire des pipelines de données robustes.

## Aller plus loin

Si vous avez besoin d'une formation ou d'une assistance technique pour la mise en oeuvre de nos solutions, contactez votre commercial ou cliquez sur [ce lien](https://www.ovhcloud.com/fr/professional-services/) pour obtenir un devis et demander une analyse personnalisée de votre projet à nos experts de l’équipe Professional Services.

Posez vos questions, faites-nous part de vos commentaires et interagissez directement avec l’équipe qui développe la Data Platform sur le [canal Discord](https://discord.gg/ovhcloud) dédié.

Si vous avez besoin d'une assistance concernant vos services OVHcloud, créez une demande depuis notre [centre d'aide](https://help.ovhcloud.com/csm?id=csm_get_help).

Rejoignez notre [communauté d'utilisateurs](https://community.ovhcloud.com/).
