Erreur PostgreSQL : division by zero
ERROR: division by zero
Une division (ou un modulo) dans la requête a atteint un dénominateur nul. Contrairement à certaines bases de données et à la plupart des environnements en virgule flottante, PostgreSQL lève une erreur au lieu de renvoyer NULL ou l'infini — donc toute division dont le dénominateur peut être nul doit dire ce qui doit se passer.
Ce que signifie cette erreur
L'erreur annule toute l'instruction (et la transaction), même si une seule ligne sur des millions avait le zéro. C'est pourquoi elle apparaît typiquement dans les agrégations et les rapports : tout fonctionne jusqu'au premier jour où un groupe est vide ou un total est nul. La solution est presque toujours le même idiome, appliqué au site de la division.
Causes fréquentes
- Taux et pourcentages où le dénominateur vient des données :
clicks / impressions,revenue / orders— parfait jusqu'à ce qu'une ligne à zéro apparaisse. - Variation en pourcentage par rapport à une base nulle.
- Zéro provenant d'un agrégat ou de COALESCE :
count(*) FILTER (...)ouCOALESCE(x, 0)alimentant un dénominateur.
Comment la diagnostiquer
Trouvez les divisions dans la requête et demandez-vous quel dénominateur peut être nul. Pour voir les lignes fautives, sélectionnez l'expression du dénominateur avec ses clés de regroupement et filtrez sur zéro — les lignes qui reviennent sont celles qui feront exploser la division.
Comment la corriger
-- L'idiome standard : dénominateur nul → résultat NULL
SELECT clicks / NULLIF(impressions, 0) AS ctr FROM stats;
-- Si vous voulez 0 (ou une autre valeur par défaut) au lieu de NULL :
SELECT COALESCE(clicks / NULLIF(impressions, 0), 0) AS ctr FROM stats;
NULLIF(x, 0)transforme le zéro en NULL, et la division par NULL donne NULL au lieu d'une erreur. Décidez délibérément si NULL (« indéfini ») ou une valeur par défaut convient au rapport.- Piège voisin tant que vous y êtes : la division entière tronque —
1/2 = 0. Castez un côté (clicks::numeric / NULLIF(impressions, 0)) quand vous voulez des fractions.
