Exporter les EAN par produit avec les ventes mensuelles en SQL PrestaShop
Requête SQL pour extraire les codes EAN13 et les quantités vendues par mois depuis PrestaShop. Export optimisé pour l'analyse des ventes par déclinaison.
En bref : Requête SQL pour croiser les codes EAN13 des déclinaisons PrestaShop avec les volumes de ventes mensuels, en gérant le piège du GROUP BY strict et les produits sans déclinaison via COALESCE.
Pourquoi exporter les EAN avec les statistiques de ventes
Le code EAN13 (European Article Number) est l'identifiant universel de chaque produit ou déclinaison dans PrestaShop. Croiser ces codes avec les volumes de ventes mensuels est indispensable pour plusieurs cas d'usage concrets :
- **Réapprovisionnement fournisseur** : envoyer les EAN des produits les plus vendus avec les quantités pour passer commande.
- **Analyse saisonnière** : identifier les pics de vente par référence et par mois.
- **Synchronisation marketplace** : Amazon, Cdiscount ou Google Shopping exigent des EAN valides — vérifier leur présence dans les commandes réelles permet de détecter les fiches incomplètes.
- **Reporting comptable** : ventiler le chiffre d'affaires par référence physique plutôt que par nom produit.
La requête SQL complète
Voici la requête qui extrait, pour chaque produit vendu, le code EAN13 de sa déclinaison et le total des quantités commandées, ventilé par année et par mois :
SELECT
YEAR(o.date_add) AS annee,
MONTH(o.date_add) AS mois,
od.product_name AS nom_produit,
SUM(od.product_quantity) AS total_vendu,
pa.ean13 AS ean13_declinaison
FROM ps_order_detail od
LEFT JOIN ps_orders o
ON o.id_order = od.id_order
LEFT JOIN ps_product_attribute pa
ON od.product_attribute_id = pa.id_product_attribute
WHERE o.valid = 1
GROUP BY
od.product_name,
pa.ean13,
YEAR(o.date_add),
MONTH(o.date_add)
ORDER BY
annee DESC,
mois DESC,
total_vendu DESC;
Remarque : Pensez à remplacer le préfixe
ps_par celui de votre installation si vous l'avez personnalisé.
Décryptage de la requête
Les tables impliquées
Pourquoi un LEFT JOIN sur `ps_product_attribute` ?
Tous les produits n'ont pas de déclinaison. Un produit simple (sans taille, couleur, etc.) aura product_attribute_id = 0 dans ps_order_detail. Le LEFT JOIN garantit que ces produits apparaissent quand même dans les résultats, avec un EAN NULL.
Pour récupérer l'EAN des produits simples (sans déclinaison), il faut ajouter une jointure sur ps_product :
SELECT
YEAR(o.date_add) AS annee,
MONTH(o.date_add) AS mois,
od.product_name AS nom_produit,
SUM(od.product_quantity) AS total_vendu,
COALESCE(pa.ean13, p.ean13) AS ean13
FROM ps_order_detail od
LEFT JOIN ps_orders o
ON o.id_order = od.id_order
LEFT JOIN ps_product_attribute pa
ON od.product_attribute_id = pa.id_product_attribute
LEFT JOIN ps_product p
ON od.product_id = p.id_product
WHERE o.valid = 1
GROUP BY
od.product_name,
COALESCE(pa.ean13, p.ean13),
YEAR(o.date_add),
MONTH(o.date_add)
ORDER BY
annee DESC,
mois DESC,
total_vendu DESC;
La fonction COALESCE prend le premier EAN non NULL : celui de la déclinaison en priorité, sinon celui du produit parent.
Le filtre `o.valid = 1`
Le champ valid de ps_orders vaut 1 uniquement pour les commandes considérées comme abouties (payées). Cela exclut automatiquement les paniers abandonnés, les commandes annulées ou en erreur de paiement. C'est le filtre standard pour toute analyse de ventes fiable.
Le piège du GROUP BY
En MySQL/MariaDB en mode strict (ONLY_FULL_GROUP_BY, activé par défaut depuis MySQL 5.7 et MariaDB 10.2), chaque colonne du SELECT qui n'est pas dans une fonction d'agrégation (SUM, COUNT, etc.) doit figurer dans le GROUP BY. Si vous obtenez l'erreur :
ERROR 1055 (42000): 'ps_product_attribute.ean13' isn't in GROUP BY
…c'est que le champ ean13 est sélectionné mais pas groupé. La solution : ajouter pa.ean13 (ou COALESCE(pa.ean13, p.ean13)) dans la clause GROUP BY, comme dans les requêtes ci-dessus.
Variantes utiles
Filtrer sur une période précise
WHERE o.valid = 1
AND o.date_add BETWEEN '2025-01-01' AND '2025-12-31'
Exporter uniquement les produits sans EAN (audit qualité)
SELECT DISTINCT
od.product_id,
od.product_name
FROM ps_order_detail od
LEFT JOIN ps_product_attribute pa
ON od.product_attribute_id = pa.id_product_attribute
LEFT JOIN ps_product p
ON od.product_id = p.id_product
WHERE COALESCE(pa.ean13, p.ean13, '') = ''
ORDER BY od.product_name;
Cette requête identifie tous les produits qui ont été vendus mais dont l'EAN est manquant — indispensable avant une synchronisation marketplace.
Ajouter la référence produit
SELECT
YEAR(o.date_add) AS annee,
MONTH(o.date_add) AS mois,
od.product_name,
od.product_reference AS reference,
SUM(od.product_quantity) AS total_vendu,
COALESCE(pa.ean13, p.ean13) AS ean13
FROM ps_order_detail od
LEFT JOIN ps_orders o
ON o.id_order = od.id_order
LEFT JOIN ps_product_attribute pa
ON od.product_attribute_id = pa.id_product_attribute
LEFT JOIN ps_product p
ON od.product_id = p.id_product
WHERE o.valid = 1
GROUP BY
od.product_name,
od.product_reference,
COALESCE(pa.ean13, p.ean13),
YEAR(o.date_add),
MONTH(o.date_add)
ORDER BY annee DESC, mois DESC, total_vendu DESC;
Exécuter la requête
Depuis le back-office PrestaShop
Allez dans Paramètres avancés → Base de données → Requête SQL et collez la requête. PrestaShop vous permet ensuite d'exporter le résultat en CSV.
En ligne de commande (recommandé pour les gros volumes)
mysql -u votre_user -p votre_base -e "
SELECT YEAR(o.date_add) AS annee, MONTH(o.date_add) AS mois,
od.product_name, SUM(od.product_quantity) AS total,
COALESCE(pa.ean13, p.ean13) AS ean13
FROM ps_order_detail od
LEFT JOIN ps_orders o ON o.id_order = od.id_order
LEFT JOIN ps_product_attribute pa ON od.product_attribute_id = pa.id_product_attribute
LEFT JOIN ps_product p ON od.product_id = p.id_product
WHERE o.valid = 1
GROUP BY od.product_name, COALESCE(pa.ean13, p.ean13),
YEAR(o.date_add), MONTH(o.date_add)
ORDER BY annee DESC, mois DESC, total DESC
" > export_ean_ventes.tsv
Le résultat sera un fichier TSV (tabulations) directement exploitable dans Excel ou Google Sheets.
Adaptation PrestaShop 8.x
La structure des tables ps_orders, ps_order_detail, ps_product et ps_product_attribute n'a pas changé entre PrestaShop 1.6 et 8.x. Ces requêtes fonctionnent donc sur toutes les versions.
Le seul point d'attention concerne le mode SQL de MariaDB/MySQL : PrestaShop 8.x exige MariaDB 10.5+ ou MySQL 8.0+, qui activent ONLY_FULL_GROUP_BY par défaut. Assurez-vous que toutes les colonnes non agrégées sont bien présentes dans le GROUP BY, comme dans les exemples fournis.
Questions fréquentes
Tout ce que vous devez savoir sur ce sujet.
Un projet PrestaShop ?
Discutons-en directement.
193 projets livrés
Lire sur le blog

Alexandre Carette
Expert PrestaShop & Architecture E-commerce
Développeur PrestaShop depuis 2014, 193 projets livrés. Je conçois des architectures headless Nuxt + PrestaShop et des outils d'automatisation IA pour les e-commerçants.