Aller au contenu principal

ChatGPT, Le Chat de Mistral AI et Gemini : Comparaison de leurs performances pour la génération de requêtes SQL

Un peu de contexte

Les chatbots ont le vent en poupe et leur nombre va en augmentant. Ces outils peuvent nous simplifier la tâche, à nous les humains, dans de nombreux domaines. En tant que développeur, j’utilise ces outils comme des accélérateurs de développement, qui vont me permettre de poser rapidement les bases du code, que j’aurai ensuite la responsabilité d'éprouver et de consolider. 

Récemment ces outils m’ont permis d'interagir plus efficacement avec une base de données SQL et c’est cette expérience que je souhaite partager. Bien qu'étant un développeur expérimenté je suis loin de maîtriser le langage SQL, sur lequel je me suis formé ponctuellement en ligne et que je ne pratique que de temps en temps lorsqu’un besoin spécifique apparaît dans le cadre d’un développement.

Ceci dit je pense que mon cas n’est pas isolé et que de nombreux développeurs ont simplement des bases en SQL, langage le plus souvent utilisé de manière indirecte, via des couches d’abstraction. Il me semble que c’est précisément pour des profils de ce type, de développeurs initiés sans être véritablement expert, où l’usage d’un chatbot peut s’avérer utile. C’est que nous allons tenter de voir ensemble à travers quelques cas concrets.

Il est important de préciser ce qu’est le SQL et ce qu’est une base de données SQL. SQL signifie Structured Query Language. C'est un langage de programmation utilisé pour gérer et manipuler des bases de données relationnelles. Et une base de données SQL, de type relationnelle donc, correspond à un ensemble de données stockées dans un format particulier, dans lequel ces données sont liées les unes aux autres. Ce qui peut notamment apporter un peu de complexité aux requêtes, notamment en cas de nombreuses jointures, c’est-à-dire d'opérations permettant de combiner les enregistrements de deux tables (ou plus) en fonction d'une condition spécifiée.

Les outils utilisés pour l’enquête

Les agents conversationnels

Dans le cadre de ce travail de recherche j’ai utilisé trois chatbots ou agents conversationnels parmi ceux disponibles sur le web en accès libre, c’est-à-dire gratuits :

ChatGPT 3.5 de Open AI

Le plus connu et le pionnier produit par la firme Open AI, située aux Etats-Unis. La version 3.5 est la version mise à disposition gratuitement, la version payante, plus performante étant à ce jour la version 4.

Le Chat de Mistral AI

L’outil poussé par des entrepreneurs français ayant fait leurs classes dans de grandes firmes aux Etats-Unis. Mistral AI a fait parlé de lui courant 2023, d’abord via un modèle de langage dit open source accessible aux développeurs. Un agent conversationnel similaire à ChatGPT a été mis en ligne en février 2024. Les performances de son modèle de langage, proches de GPT-4 ont été notamment mises en avant.

Gemini de Google

Gemini de Google a été mis à disposition début 2024 après avoir été présenté à grand renfort de communication. Il s’agit d’un agent conversationnel, tout comme ChatGPT, qui a l’avantage d'être intégré à l'écosystème Google et est dont le modèle de langage est voué à jouer un rôle croissant dans le moteur de recherche.

Le moteur de base de données

Je me suis basé sur une base de données MySQL 5.7, plus ancienne que sa remplaçante MySQL 8 mais encore beaucoup utilisée. N’hésitez pas à me proposer des retours d’usage avec d’autres moteurs de base de données.

Pour ce qui est du jeu de données utilisé pour les tests j’ai demandé tout simplement à un chatbot de me suggérer des requêtes de création de TABLE et des requêtes pour insérer quelques dizaines d’entrées, que j’ai ensuite éditées à ma guise à la main. Et je dois dire que cela a plutôt bien fonctionné, en deux ou trois prompts.

Mise en pratique

Avant de commencer, une petite digression, sous la forme d’une question existentielle : a-t-on véritablement besoin d'interagir directement en SQL avec une base ? 
En effet, en tant que développeur, il est de plus en plus rare qu’on ait à rédiger directement des requêtes SQL dans notre code. Les frameworks, CMS et librairies mis à disposition dans la plupart des langages de programmation modernes ajoutent une couche de langage intermédiaire facilitant la rédaction de requête et la rendant agnostique, c’est-à-dire lui permettant de se greffer à différents types de moteur de base de données (SQLite, MySQL/MariaDB, PostgreSQL pour citer les plus répandus).

En PHP, on utilisera par exemple le plus souvent a minima la librairie PDO qui facilite et sécurise la rédaction de requête. Pour Java ce sera JDBC et pour Python l’API intégrée DB-API associée à un module spécifique au type de base.

Cependant il arrive qu’on puisse avoir besoin d’un accès instantané aux données d'une base de données SQL, pour obtenir rapidement des informations sur les contenus de notre application, surtout dans la mesure où ces informations sont très spécifiques et ne sont pas directement mises à disposition sur le site.

Prenons en exemple dans le cadre de cet article un cas typique assez simple : un site événementiel. Une base de données relationnelle peut permettre de stocker une liste d'évènements, une liste de lieux et une liste de catégories thématiques que l’on souhaite afficher à l’utilisateur. Chaque évènement peut conserver une référence à l’information du lieu où il se déroule ainsi qu'à une ou plusieurs catégories.

Cette structure de l’information permet d’afficher au sein d’un site web, en fonction des choix de l’utilisateur, une liste d'évènements pour un lieu donné ou bien pour une catégorie spécifique.

Voyons à présent concrètement ce que les différents chatbots disponibles en libre accès sur le web ont à nous apporter pour rédiger une requête SQL.

Requête n°1 : une requête simple résolue efficacement

Commençons par une requête simple. Nous souhaiterions savoir combien d'évènements dans la catégorie reggae ont eu lieu à Paris, en France.

Voici le type de prompt rapide à rédiger qui permettra d’obtenir une requête satisfaisante.

Agis en expert SQL. 
Rédige une requête me permettant de récupérer le nombre d'événements dans la catégorie reggae ayant lieu à Paris en France. 
La table events comprend les événements et a les colonnes id, ville et pays. La table category comprend les catégories et dispose d’une colonne id et d’une colonne name.

Prenons le temps de décomposer les instructions. 
La première étape, classique dans l’usage d’un chatbot, est de donner un rôle à notre interlocuteur virtuel, pour nous assurer de la pertinence de sa réponse.
Ensuite, deux éléments essentiels à décrire pour obtenir une requête qui correspond au besoin : 
- le résultat attendu de la requête 
- la source de données, c’est-à-dire les tables et les colonnes que l’on veut cibler ainsi que la manière dont elles sont liées.

Bien sûr, plus le besoin sera complexe et plus la description devra être précise.

La réponse de ChatGPT (Open AI)

Voici une requête SQL pour récupérer le nombre d'événements dans la catégorie "reggae" ayant lieu à Paris en France :

SELECT COUNT(*) AS nombre_evenements
FROM events
JOIN category ON events.category_id = category.id
WHERE category.name = 'reggae'
AND events.ville = 'Paris'
AND events.pays = 'France';

Cette requête utilise une jointure entre les tables "events" et "category" sur la colonne "category_id" de la table "events" et la colonne "id" de la table "category" pour récupérer le nombre d'événements dans la catégorie "reggae". Ensuite, elle applique des conditions pour filtrer les événements ayant lieu à Paris en France. Enfin, elle compte le nombre d'événements correspondants.

Analyse : la réponse de ChatGPT est concise est efficace. La requête est correcte. Le chatbot d’OpenAI part du principe que la liaison entre un événement et une catégorie est située dans la TABLE events et non pas dans une TABLE indépendante. Il faut dire que je n’avais pas préciser la nature de cette liaison et que la solution proposée apparaît comme la plus simple. Mais on aurait pu espérer un peu plus de commentaire sur ce parti pris.

La réponse du Chat (Mistral AI)

Je suppose qu'il existe également une table de liaison entre les tables "events" et "category", que j'appellerai "event_category" ayant les colonnes "event_id" et "category_id". Voici la requête SQL :

SELECT COUNT(e.id) as nombre_evenements
FROM events e
JOIN event_category ec ON e.id = ec.event_id
JOIN category c ON ec.category_id = c.id
WHERE c.name = 'reggae' AND e.ville = 'Paris' AND e.pays = 'France';

Cette requête permet de récupérer le nombre d'événements dans la catégorie "reggae" ayant lieu à Paris en France.

Analyse : réponse également correcte de la part du Chat Mistral. On constate de légères nuances dans la syntaxe, pas forcément significatives pour notre cas d’usage. 
Mais on note surtout une jointure supplémentaire, c’est-à-dire l’appel à une TABLE supplémentaire, stockant la relation un événement et une catégorie. Isoler la relation entre deux entités d’une base de données relationnelles est un choix architectural assez classique. 
Le Chat de Mistral AI fournit une description un peu plus succincte et moins technique. 
Contrairement à ChatGPT il assume qu’il a déduit une information que je n’avais pas fournie.

La réponse de Gemini (Google)

Requête SQL pour compter les événements reggae à Paris

SELECT COUNT(*) AS nombre_evenements
FROM events e
INNER JOIN category c ON e.category_id = c.id
WHERE c.name = 'reggae'
AND e.ville = 'Paris'
AND e.pays = 'France';

Utilisez ce code avec précaution.

Explication de la requête:

  1. SELECT COUNT(*) AS nombre_evenements: Cette ligne sélectionne le nombre d'enregistrements de la table events et l'assigne à l'alias nombre_evenements.
  2. FROM events e: Cette ligne indique que la requête sélectionne les données de la table events et lui donne l'alias e.
  3. INNER JOIN category c ON e.category_id = c.id: Cette ligne joint la table events à la table category sur la colonne category_id. Cela permet de filtrer les événements par catégorie.
  4. WHERE c.name = 'reggae': Cette ligne filtre les événements dont la catégorie est reggae.
  5. AND e.ville = 'Paris': Cette ligne filtre les événements qui ont lieu à Paris.
  6. AND e.pays = 'France': Cette ligne filtre les événements qui ont lieu en France.

Résultat:

Le résultat de la requête sera un seul enregistrement avec une seule colonne nombre_evenements qui contient le nombre d'événements reggae à Paris en France.

Analyse : une requête également fonctionnelle de la part de Google Gemini. Une syntaxe encore légèrement nuancée par rapport aux deux autres, à la marge. 
Et même présupposition que ChatGPT pour la liaison événement/catégorie : l’ajout d’une colonne category_id dans la TABLE events. 
Par ailleurs, Gemini est généreux dans sa description et explicite ligne par ligne ce que fait la requête

Requête n°2 : attention aux doublons

Voici un autre exemple de requête. Cette fois en précisant la nature de la liaison entre un évènement et une catégorie.

Agis en expert SQL.
Rédige une requête me permettant de récupérer les événements ayant lieu en France dont la catégorie n'est ni jazz ni classique et dont le titre contient le mot festival.
La table events comprend les événements et a les colonnes id, titre, ville, pays. 
La table category comprend les catégories et dispose d’une colonne id et d’une colonne name. 
La table event_category contient les liaisons entre un évènement et une ou plusieurs catégories et a les colonnes event_id et category_id

La réponse de ChatGPT (Open AI)

Vous pouvez utiliser une requête SQL avec une jointure entre les tables events, event_category, et category, tout en utilisant des clauses WHERE pour filtrer les événements selon vos critères. Voici comment vous pouvez le faire :

SELECT e.id, e.titre, e.ville, e.pays
FROM events e
INNER JOIN event_category ec ON e.id = ec.event_id
INNER JOIN category c ON ec.category_id = c.id
WHERE e.pays = 'France'
AND c.name NOT IN ('jazz', 'classique')
AND e.titre LIKE '%festival%';

Cette requête sélectionne les événements de la table events en France (e.pays = 'France'), dont la catégorie n'est ni jazz ni classique (c.name NOT IN ('jazz', 'classique')), et dont le titre contient le mot "festival" (e.titre LIKE '%festival%').

Analyse : explication simple et efficace de la requête. Ceci dit les résultats renvoyés comprennent des doublons, ce qui n’est pas normal au vu de la base ciblée, qui ne comporte que des entrées uniques. En titillant un peu ChatGPT on peut arriver à notre fin.

 

Comment éviter des doublons ?

Pour éviter les doublons dans les résultats de la requête, vous pouvez utiliser DISTINCT dans la clause SELECT. Voici comment modifier la requête pour inclure DISTINCT :

SELECT DISTINCT e.id, e.titre, e.ville, e.pays
FROM events e
JOIN event_category ec ON e.id = ec.event_id
JOIN category c ON ec.category_id = c.id
WHERE e.pays = 'France'
AND c.name NOT IN ('jazz', 'classique')
AND e.titre LIKE '%festival%';

En ajoutant DISTINCT, la requête ne renverra qu'une seule occurrence de chaque combinaison unique de e.id, e.titre, e.ville et e.pays, évitant ainsi les doublons dans les résultats.

Analyse : La requête est bonne même si me voir proposer également une solution avec GROUP BY, permettant aussi d’aboutir au résultat souhaité, ne m’aurait pas déplue.

La réponse du Chat (Mistral AI)

Voici une requête SQL qui devrait répondre à votre demande :

SELECT e.*
FROM events e
JOIN event_category ec ON e.id = ec.event_id
JOIN category c ON ec.category_id = c.id
WHERE e.pays = 'France'
AND c.name NOT IN ('jazz', 'classique')
AND e.titre LIKE '%festival%';

Cette requête va sélectionner les événements en France dont la catégorie n'est ni jazz ni classique et dont le titre contient le mot 'festival'. Elle joint les tables 'events', 'event_category' et 'category' sur les clés appropriées pour obtenir les informations nécessaires.

Analyse : requête très proche de celle de ChatGPT. Même style concis que pour la 1ère requête réalisée avec ce chatbot et même constat que pour ChatGPT concernant la qualité de la requête, qui renvoie des doublons. Suite à ma relance Le Chat Mistral AI a corrigé également le tir avec une réponse très semblable à ChatGPT.

La réponse de Gemini (Google)

Requête SQL pour récupérer les événements en France

SELECT e.id, e.titre, e.ville, e.pays
FROM events e
INNER JOIN event_category ec ON e.id = ec.event_id
INNER JOIN category c ON ec.category_id = c.id
WHERE e.pays = 'France'
AND c.name NOT IN ('jazz', 'classique')
AND e.titre LIKE '%festival%';

Utilisez ce code avec précaution.

Explication de la requête:

  1. SELECT e.id, e.titre, e.ville, e.pays: On sélectionne les colonnes id, titre, ville et pays de la table events.
  2. INNER JOIN event_category ec ON e.id = ec.event_id: On joint la table events à la table event_category sur la colonne id.
  3. INNER JOIN category c ON ec.category_id = c.id: On joint la table event_category à la table category sur la colonne category_id.
  4. WHERE e.pays = 'France': On filtre les événements qui ont lieu en France.
  5. AND c.name NOT IN ('jazz', 'classique'): On exclut les événements dont la catégorie est "jazz" ou "classique".
  6. AND e.titre LIKE '%festival%': On filtre les événements dont le titre contient le mot "festival".

Résultat:

La requête renvoie une liste d'événements qui ont lieu en France, dont la catégorie n'est ni jazz ni classique et dont le titre contient le mot "festival". La liste contient les informations suivantes pour chaque événement :

  • ID
  • Titre
  • Ville
  • Pays

Analyse : Requête similaire à celles de ses concurrents, avec des doublons à la clé. Concernant le style, celui de Google Gemini semble décidément plus verbeux et nous guide pas à pas dans les spécificités de la requête. Sa réponse pour supprimer les doublons, ci-dessous, présente les différentes solutions, dont le GROUP BY comme alternative, et est donc plus complète que celle de GPT ou Mistral.

Pour éviter les doublons dans le résultat de votre requête, vous pouvez utiliser la clause DISTINCT après le mot clé SELECT.

Requête avec DISTINCT:

SELECT DISTINCT e.id, e.titre, e.ville, e.pays
FROM events e
INNER JOIN event_category ec ON e.id = ec.event_id
INNER JOIN category c ON c.id = ec.category_id
WHERE e.pays = 'France'
AND c.name NOT IN ('jazz', 'classique')
AND e.titre LIKE '%festival%'

Utilisez ce code avec précaution.

Explication:

  • La clause DISTINCT permet de s'assurer que chaque ligne du résultat est unique.
  • Dans cette requête, elle est utilisée pour garantir que chaque événement n'apparaît qu'une seule fois dans le résultat.

Autres options pour éviter les doublons:

  • Vous pouvez utiliser la clause GROUP BY pour regrouper les événements par une ou plusieurs colonnes et afficher une seule ligne pour chaque groupe.
  • Vous pouvez utiliser la clause ORDER BY pour trier les événements par une ou plusieurs colonnes et afficher les événements uniques en premier.

Choisir la meilleure option:

La meilleure option pour éviter les doublons dépend de vos besoins spécifiques.

  • Si vous souhaitez uniquement afficher les événements uniques, la clause DISTINCT est la solution la plus simple.
  • Si vous souhaitez afficher des informations agrégées sur les événements, la clause GROUP BY est une meilleure option.
  • Si vous souhaitez afficher les événements uniques dans un ordre spécifique, la clause ORDER BY peut être utilisée en conjonction avec DISTINCT ou GROUP BY.

Requête n°3 : les chatbots poussés dans leurs retranchements

Agis en expert SQL. Rédige une requête me permettant de récupérer les événements ayant lieu à Lyon ou à Saint-Etienne dont la catégorie est pop ou jazz, dont le titre contient le mot concer sans t et remplace ces entrées par le mot concert avec un t. La table events comprend les événements et a les colonnes id, titre, ville, pays. La table category comprend les catégories et dispose d’une colonne id et d’une colonne name. La table event_category contient les liaisons entre un évènement et une ou plusieurs catégories et a les colonnes event_id et category_id

La réponse de ChatGPT (Open AI)

Voici la requête SQL correspondant à vos critères :

SELECT e.id, REPLACE(e.titre, 'concer', 'concert') AS titre, e.ville, e.pays
FROM events e
JOIN event_category ec ON e.id = ec.event_id
JOIN category c ON ec.category_id = c.id
WHERE (e.ville = 'Lyon' OR e.ville = 'Saint-Etienne')
AND (c.name = 'pop' OR c.name = 'jazz')
AND e.titre LIKE '%concer%'

Cette requête récupère les événements ayant lieu à Lyon ou à Saint-Etienne, de catégorie "pop" ou "jazz", dont le titre contient le mot "concer". La fonction REPLACE est utilisée pour remplacer "concer" par "concert".

Analyse : La requête fournie ne répond pas au besoin et là on voit bien les limites du chatbot. En effet celui-ci a fait une analyse strictement logique de mon prompt sans déduire que je souhaitais corriger une faute d’orthographe.

La solution proposée va remplacer “concer“ dans le mot “concert“ et ne va pas donc pas simplement corriger le mot “concer“ à qui il manque un t mais va aussi transformer concert en “concertt”, ce qui n’est pas ce que je souhaitais.

Par ailleurs il s’agit d’une requête SELECT ce qui veut dire que les entrées en base ne vont pas être modifiées puisqu’il aurait fallu une requête de type UPDATE pour cela.

La réponse du Chat (Mistral AI)

Voici une requête SQL qui devrait répondre à votre demande. Elle met à jour le titre des événements dans la table "events" en fonction des critères spécifiés. Notez que SQL n'est pas sensible à la casse, sauf si vous utilisez des collations spécifiques.

UPDATE events
SET titre = REPLACE(titre, 'concer', 'concert')
WHERE ville IN ('Lyon', 'Saint-Etienne')
AND id IN (
    SELECT event_id
    FROM event_category
    JOIN category ON event_category.category_id = category.id
    WHERE category.name IN ('pop', 'jazz')
)
AND titre LIKE '%concer%';

Cette requête fonctionne en deux parties. La première partie est la clause UPDATE, qui remplace 'concer' par 'concert' dans le titre de l'événement. La deuxième partie est la clause WHERE, qui filtre les événements en fonction de la ville et de la catégorie. La sous-requête est utilisée pour récupérer les identifiants des événements qui appartiennent aux catégories 'pop' ou 'jazz'.

Analyse : la solution proposée est un peu plus proche de mes attentes puisque cette fois on obtient du premier coup une requête UPDATE, qui va réellement modifier les entrées en base. Mais Le Chat MIstral commet toujours une erreur d’interprétation en restant strictement logique.

La réponse de Gemini (Google)

Requête SQL pour récupérer les événements à Lyon ou Saint-Etienne avec les catégories pop ou jazz et le mot "concer" sans "t"

SELECT e.id,
       REPLACE(e.titre, 'concer', 'concert') AS titre,
       e.ville,
       e.pays
FROM events e
INNER JOIN event_category ec ON e.id = ec.event_id
INNER JOIN categories c ON ec.category_id = c.id
WHERE (e.ville = 'Lyon' OR e.ville = 'Saint-Etienne')
AND (c.name = 'pop' OR c.name = 'jazz')
AND e.titre LIKE '%concer%';

Utilisez ce code avec précaution.

Explication de la requête:

  1. SELECT: On sélectionne les colonnes id, titre, ville et pays de la table events.
  2. REPLACE: On remplace le mot "concer" par "concert" dans la colonne titre.
  3. INNER JOIN: On joint la table events à la table event_category sur la colonne id.
  4. INNER JOIN: On joint la table event_category à la table categories sur la colonne category_id.
  5. WHERE: On filtre les événements dont la ville est 'Lyon' ou 'Saint-Etienne' et dont la catégorie est 'pop' ou 'jazz'.
  6. LIKE: On filtre les événements dont le titre contient le mot "concer".

Résultat:

La requête retourne une table contenant les événements qui correspondent aux critères définis. La colonne titre aura le mot "concert" avec un "t".

Analyse : même problème de communication qu’avec ChatGPT ; je reçois une requête SELECT et non une requête d’UPDATE. De plus la première requête proposée comportait des erreurs de syntaxe (Table category nommée categories) et n'était pas utilisable en l'état. J’ai dû faire un nouveau prompt pour aboutir au résultat ci-dessus. J’aurais souhaité au moins que le chatbot me propose les deux solutions, dans le doute, pour que j’approfondisse celle qui me convient.

Deuxième tour de table pour la requête n°3

Face au constat d'échec de la première tentative auprès des trois agents conversationnels, je me dis que j’aurais peut-être dû être un peu plus précis et logique dans mon énoncé. 
Après un certain nombre de tâtonnements j’en arrive au prompt suivant, qui délimite davantage mon besoin :

Rédige une ou plusieurs requêtes me permettant de récupérer les événements ayant lieu à Lyon ou à Saint-Etienne dont la catégorie est pop ou jazz, dont le titre contient le mot concer sans t puis de remplacer et de mettre à jour ces entrées par le mot concert avec un t. La table events comprend les événements et a les colonnes id, titre, ville, pays. La table category comprend les catégories et dispose d’une colonne id et d’une colonne name. La table event_category contient les liaisons entre un évènement et une ou plusieurs catégories et a les colonnes event_id et category_id.

Dans les chaînes de caractères recherchées concer doit être suivi et précédé d'un espace. Sauf s'il est en début de chaîne : dans ce cas-là il n'est précédé d'aucun caractère. Et sauf s'il est en fin de chaîne : dans ce cas-là il n'est suivi d'aucun caractère. La requête doit être obligatoirement compatible avec les différents versions de MySQL (5 et 8) et de PostgreSQL.

La réponse de ChatGPT (Open AI)

Requête extraite de la réponse de ChatGPT :

-- Mise à jour des titres des événements
UPDATE events
SET titre = REPLACE(titre, ' concer', ' concert')
WHERE (ville = 'Lyon' OR ville = 'Saint-Etienne')
  AND (titre LIKE '% concer%' OR titre LIKE 'concer%');

Analyse : ChatGPT m’a proposé deux requêtes : un SELECT et un UPDATE. La requête UPDATE, qui m’intéresse, remplace bien les occurrences de “concer” par “concert” mais seulement quand le mot est précédé et suivi d’un espace, pas dans le cas où il est en début ou fin de chaîne. Je n’obtiendrai pas de solution plus convaincante auprès de ChatGPT après lui avoir communiqué l’erreur.

Ceci dit, cette requête peut être utilisée plusieurs fois en ajustant les chaînes de caractères à rechercher et à remplacer donc reste quand même une ressource sur laquelle m’appuyer si je ne souhaite pas me creuser la tête pour trouver la requête parfaite qui fait tout en une seule fois.

La réponse du Chat (Mistral AI)

Requête extraite de la réponse du Chat

UPDATE events e
JOIN event_category ec ON e.id = ec.event_id
JOIN category c ON ec.category_id = c.id
SET e.titre = REPLACE(e.titre, 'concer', 'concert')
WHERE (e.ville = 'Lyon' OR e.ville = 'Saint-Etienne')
AND c.name IN ('pop', 'jazz')
AND (e.titre LIKE 'concer%' OR e.titre LIKE '% concer%' OR e.titre LIKE '% concer %');

Deux requêtes également proposées. La requête d’UPDATE remplace bien les occurrences de “concer” par “concert” mais elle remplace aussi “concer” dans “concert” donc on obtient en bout de traitement “concertt” avec deux t et on reste bloqué au même stade qu’avec le premier prompt que nous avions proposé.

Mais quand je souligne l’erreur le chatbot se rattrape et me donne la bonne requête :

Je comprends le problème maintenant. Pour éviter de remplacer 'concer' dans 'concert', vous pouvez utiliser la fonction CASE pour vérifier si 'concer' est un mot entier ou non avant de le remplacer. Voici la requête mise à jour :

UPDATE events e
JOIN event_category ec ON e.id = ec.event_id
JOIN category c ON ec.category_id = c.id
SET e.titre = CASE
    WHEN e.titre LIKE 'concer%' AND e.titre NOT LIKE 'concert%' THEN REPLACE(e.titre, 'concer', 'concert')
    WHEN e.titre LIKE '% concer%' AND e.titre NOT LIKE '% concert%' THEN REPLACE(e.titre, ' concer', ' concert')
    WHEN e.titre LIKE '% concer %' AND e.titre NOT LIKE '% concert %' THEN REPLACE(e.titre, ' concer ', ' concert ')
    ELSE e.titre
END
WHERE (e.ville = 'Lyon' OR e.ville = 'Saint-Etienne')
AND c.name IN ('pop', 'jazz')
AND (e.titre LIKE 'concer%' OR e.titre LIKE '% concer%' OR e.titre LIKE '% concer %');

Cette requête devrait maintenant remplacer correctement 'concer' par 'concert' sans affecter les occurrences de 'concert'.

Bingo ! Même si cela a demandé un peu de patience.

La réponse de Gemini (Google)

Extrait de la réponse Gemini

-- MySQL
UPDATE events e
SET e.titre = REPLACE(e.titre, ' concer ', ' concert ')
WHERE e.id IN (
    SELECT e.id
    FROM events e
    JOIN event_category ec ON e.id = ec.event_id
    JOIN categories c ON ec.category_id = c.id
    WHERE e.ville IN ('Lyon', 'Saint-Etienne')
    AND c.name IN ('pop', 'jazz')
    AND e.titre LIKE '% concer %'
);
-- PostgreSQL
UPDATE events e
SET e.titre = REPLACE(e.titre, ' concer ', ' concert ')
WHERE e.id IN (
    SELECT e.id
    FROM events e
    JOIN event_category ec ON e.id = ec.event_id
    JOIN categories c ON ec.category_id = c.id
    WHERE e.ville IN ('Lyon', 'Saint-Etienne')
    AND c.name IN ('pop', 'jazz')
    AND e.titre LIKE '% concer %'
);

Analyse : La requête UPDATE proposée pour MySQL n’est pas bonne et j’obtiens l’erreur suivante : "You can't specify target table 'e' for update in FROM clause." Pas de meilleure solution proposée par Gemini après avoir fait part de l’erreur. Je suis bloqué. Bien sûr, avec de l’imagination et du cadrage on devrait pouvoir aboutir à ses fins mais au prix de pas mal de contorsions langagières et de beaucoup de temps passé à affiner et à itérer.

Conclusion

Les chatbots en libre accès peuvent nous aider

Les trois agents conversationnels utilisés m’ont permis de rédiger très rapidement une requête plutôt simple et que j’aurais mis davantage de temps à rédiger, faute de me rappeler précisément la syntaxe de base en SQL, que je ne pratique pas au quotidien.

Les chatbots sont loin d'être parfaits

Pour des requêtes plus complexes les résultats sont mitigés. Sans un minimum de précaution et de connaissance en SQL il paraît difficile de composer une requête SQL avec une certaine complexité. Pour mettre toutes les chances de sont côtés l’idéal est : 
- d’avoir au minimum des notions de SQL 
- de rédiger un prompt logique laissant un minimum de place à l’interprétation 
- de décomposer au maximum les problèmes pour obtenir une solution ciblée. 
Dans le cadre de la dernière requête, plus on ajoute de variantes dans la chaîne de caractères à remplacer plus on augmente le risque que le chatbot s’emmêle les pinceaux. Décomposer une requête complexe en plusieurs petites requêtes simples peut parfois être une solution quand on a pas de contraintes en terme de quantité de requêtes.

La qualité de la réponse varie d’un agent à l’autre

Le Chat Mistral est celui qui semble avoir le mieux compris le prompt le plus abouti dans le cadre d’une requête plus complexe. Mais ChatGPT a également fourni une réponse exploitable. De son côté Gemini a sêché mais a été très pédagogue dans le cas des autres requêtes un peu plus simples.

On peut conclure que chacun des agents conversationnels a des atouts à faire valoir. Cependant, si on observe des nuances avec les quelques prompts présentés dans cette étude, il est toutefois difficile de faire un diagnostic définitif avec un si petit échantillon, d'autant que ces outils sont en évolution constante. 

On peut constater en tout cas que rien ne remplace un œil d’expert, qui est d’autant plus important que le besoin se complexifie et comporte une part de criticité (notamment dans le cas d’une requête qui va éditer ou supprimer des entrées en base !). Cela fait partie des conclusions plus générales qu’on peut tirer de cette étude (et qui ont été déjà été faites par ailleurs). Tout comme le fait de savoir qu’il y a plusieurs alternatives dans le monde des chatbots, qui se complètent et qui permettent d’itérer et de comparer plusieurs solutions à un problème donné.