Quersumme berechnen

Mitunter trifft man auf den Fall eine Quersumme, beispielsweise in Form einer Prüfziffer, berechnen zu müssen. In PHP ist das ein einfacher Vorgang, der ungefähr so aussehen kann:

var_dump(array_sum(str_split('123')));

Ein ziemlich übersichtlicher Einzeiler, der hinsichtlich Parameterprüfung sicher noch verfeinert und in eine Funktion gepackt werden kann. In MySQL ist eine Umsetzung schwieriger. Die String-Funktionen bieten keinen Pendant zu PHP str_split() an. Wer kurz  im Netz sucht, erhält in der Regel Lösungsansätze, die auf Stored Procedures und Schleifen aufbauen. Diese möchte ich an dieser Stelle zwar nicht schlecht reden. Dennoch wäre eine  Lösung wünschenswert, die einfach in einen Select eingebaut werden kann.

Um dies zu erreichen muss man nicht zwangsläufig zwangsläufig über alle Ziffern einer Zahl iteratieren und die Ziffern aufsummieren. Eine alternative Idee die Quersumme zu bilden, fußt auf der Zählung der Vorkommen einzelner Ziffern. Jene Vorkommen werden mit dem Wert der Ziffer multipliziert und schließlich kommuliert. Sie ergeben so die Quersumme. Die nachfolgende Formel, soll diesen Vorgang noch einmal verdeutlichen:

Quersumme
Quersumme

Das Zählen von Vorkommen einzelner Ziffern kann widerum durch die nachfolgende Formel erreicht werden – womit erneut eine Schleife vermieden wird.

Vorkommen
Vorkommen

Die Funktion length mit i und -i steht für die Länge des Strings mit und ohne der Ziffer(n) i.
Dadurch entsteht eine Differenz, die die Anzahl der Ziffer i im besagten String str angibt.

Übertragen wir die Erkenntnisse nach MySQL. Das Vorkommen der Ziffer 1 wird beispielsweise folgendermaßen ermittelt:

(LENGTH(field) - LENGTH(REPLACE(field, '1', ''))

Ein Aufruf von REPLACE hilft dabei die Stringlänge von field ohne die Zahl eins festzustellen. Kombiniert man die obige Formel der Quersumme und die der Vorkommen bestimmter Ziffern, kann die Bildung der Quersumme in MySQL so aussehen:

SELECT
(LENGTH(field) - LENGTH(REPLACE(field, '1', '')) +
(LENGTH(field) - LENGTH(REPLACE(field, '2', '')))  * 2 +
(LENGTH(field) - LENGTH(REPLACE(field, '3', '')))  * 3 +
(LENGTH(field) - LENGTH(REPLACE(field, '4', '')))  * 4 +
(LENGTH(field) - LENGTH(REPLACE(field, '5', '')))  * 5 +
(LENGTH(field) - LENGTH(REPLACE(field, '6', '')))  * 6 +
(LENGTH(field) - LENGTH(REPLACE(field, '7', '')))  * 7 +
(LENGTH(field) - LENGTH(REPLACE(field, '8', '')))  * 8 +
(LENGTH(field) - LENGTH(REPLACE(field, '9', '')))  * 9 )  
AS checksum
FROM ...

Nicht äußerst kurz, aber nicht länger als eine Stored Procedure und deutlich praktischer in der sporadischen Anwendung. Der Vorgang ist bereits insofern optimiert, dass die Ziffer 0 nicht einberechnet wurde, da sie keinen Einfluss auf die Summe besitzt. Außerdem wurde die Multiplikation mit der Ziffer 1 entfernt, da auch sie überflüssig ist.

Zum Schluss noch ein paar weiterführende Links zum Thema:

  • http://de.wikipedia.org/wiki/Quersumme
  • http://dev.mysql.com/doc/refman/5.6/en/string-functions.html

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *