APSQL

Utiliser la commande Merge

L'instruction MERGE est présente à partir de la version 2008 de SQL Server. Cette instruction va permettre de consolider des données de synthèses par rapport à des données de production et ceci avec une seule requête qui permettra aussi bien d'ajouter que de modifier ou bien de supprimer des informations.

Par exemple la base possède une table des clients dans laquelle on trouve, parmis les colonnes, une colonne représentant la ville. D'autre part la base possède la table repartitionGeographique qui permet de connaître pour chaque ville le nombre de clients présents. Bien entendu lorsqu'une ville ne possède pas de clients, elle ne doit pas apparaître dans cette liste. Acondition qu'il n'existe pas deux villes portant le même nom, la table repartitionGeographique peut être défini à l'aide du script suivant:

CREATE TABLE repartitionGeographique(
  ville nvarchar(80),
  nbreClients int);

Au départ la table peut être valorisé avec une requête insert du type:

INSERT INTO repartitionGeographique(ville, nbreClients)
SELECT  ville, COUNT(*)
  FROM clients  
  GROUP BY ville;

Par la suite la table des clients va évoluer (nouveau clients, déménagement, suppression de certains clients, …) et donc leur répartitin géographique également. La question qui se pose alors est comment mettre à jour la table repartitionGeographique?

L'instruction MERGE est parfaitement adapté à ce cas de figure.

L'instruction MERGE va travailler avec une source et une destination des données. Dans l'exemple présent la source de données est la requête : SELECT ville, COUNT(*) as nbre FROM clients GROUP BY ville et la destination est la table repartitionGeographique. Les données seront rapprochées par rapport au nom de la ville. 3 cas peuvent alors se produire:

  • il y a correspondance (WHEN MATCHED) , il faut donc faire un UPDATE
  • la ville est présente dans la table des clients (SOURCE) mais pas dans la table repartitionGeographique (WHEN NOT MATCHED), il faut donc faire un INSERT
  • la ville n'est pas présente dans la table des clients (SOURCE) mais est présente dans la table repartitionGeographique (WHEN NOT MATCHED BY SOURCE) il faut donc faire un DELETE

La requête MERGE finale peut donc s'écrire de la façon suivante:

WITH synthese (ville, nbre) AS (SELECT  ville, COUNT(*) FROM clients GROUP BY ville)
MERGE INTO repartitionGeographique
  USING synthese
  ON repartitionGeographique.ville=synthese.ville
  WHEN MATCHED THEN update set nbreClients=nbre
  WHEN NOT MATCHED THEN insert values(ville, nbre)
  WHEN NOT MATCHED BY SOURCE THEN delete;