MySQL - wie kann man die Postleitzahl mit „0“ versehen?

89

In meiner MySQL InnoDB-Datenbank habe ich schmutzige Postleitzahldaten, die ich bereinigen möchte.

Die sauberen Postleitzahldaten sind, wenn ich alle 5 Ziffern für eine Postleitzahl habe (z. B. "90210").

Aus irgendeinem Grund habe ich in meiner Datenbank festgestellt, dass bei Postleitzahlen, die mit einer "0" beginnen, die 0 gelöscht wurde.

" Holtsville, New York " mit Postleitzahl " 00544" wird in meiner Datenbank als " 544" gespeichert

und

" Dedham, MA " mit Postleitzahl " 02026" wird in meiner Datenbank als " 2026" gespeichert .

Welches SQL kann ich auf dem Frontpad "0" für eine Postleitzahl ausführen, die nicht 5-stellig ist? Das heißt, wenn die Postleitzahl 3-stellig ist, das vordere Pad "00". Wenn die Postleitzahl 4-stellig ist, ist das vordere Pad nur "0".

UPDATE :

Ich habe gerade die Postleitzahl in Datentyp VARCHAR (5) geändert.

TeddyR
quelle
3
Es scheint, dass die Tabellenspalte für die Postleitzahl vom Typ Nummer ist und das Problem verursacht. In diesem Fall müssen Sie den Datentyp ändern, um die Zeichendaten beizubehalten.
Kangkan
1
@ Kangkan, du bist richtig. Mein Datentyp war eine Nummer. Ich habe gerade die Postleitzahl in varchar (5) konvertiert. Wie gehe ich nun zur Startseite <5-stellige Postleitzahlen mit einer "0"?
TeddyR
1
Es ist besser, CHAR anstelle von VARCHAR zu verwenden. Es wird Abfragen um ein Vielfaches beschleunigen, wenn die Tabelle groß wird (nur wenn alle anderen Spalten eine feste Größe haben)
quantumSoup
2
Beachten Sie auch, dass Postleitzahlen aus anderen Ländern nicht immer 5 Zeichen sind.
Bill Karwin

Antworten:

214

Speichern Sie Ihre Postleitzahlen als CHAR (5) anstelle eines numerischen Typs oder lassen Sie sie von Ihrer Anwendung mit Nullen auffüllen, wenn Sie sie aus der Datenbank laden. Eine Möglichkeit, dies mit PHP zu tun, indem Sie sprintf():

echo sprintf("%05d", 205); // prints 00205
echo sprintf("%05d", 1492); // prints 01492

Oder Sie können MySQL Pad für Sie mit LPAD():

SELECT LPAD(zip, 5, '0') as zipcode FROM table;

Hier ist eine Möglichkeit, alle Zeilen zu aktualisieren und aufzufüllen:

ALTER TABLE `table` CHANGE `zip` `zip` CHAR(5); #changes type
UPDATE table SET `zip`=LPAD(`zip`, 5, '0'); #pads everything
quantumSoup
quelle
Ich möchte meine Daten in der Datenbank selbst bereinigen. Kennen Sie das Äquivalent dazu mit SQL?
TeddyR
1
Ich habe den folgenden Code ausgeführt, mit dem es funktioniert hat: "UPDATE Tabellenname SET zip = LPAD (zip, 5, '0');"
TeddyR
Ich würde argumentieren, dass diese "akzeptierte" Antwort nicht so gut ist wie die ZEROFILLAntworten.
Rick James
Ein Fehler in dieser Antwort. Wenn der Standardwert CHARACTER SETutf8 ist, CHAR(5)werden unnötigerweise 15 Bytes benötigt!
Rick James
19

Sie müssen die Länge der Postleitzahl bestimmen (die meiner Meinung nach 5 Zeichen lang sein sollte). Dann müssen Sie MySQL anweisen, die Zahlen auf Null zu setzen.

Angenommen, Ihre Tabelle heißt mytableund das betreffende Feld lautet zipcode: Typ smallint. Sie müssen die folgende Abfrage ausgeben:

ALTER TABLE mytable CHANGE `zipcode` `zipcode`
    MEDIUMINT( 5 ) UNSIGNED ZEROFILL NOT NULL;

Der Vorteil dieser Methode ist, dass Ihre Daten intakt bleiben, beim Einfügen / Aktualisieren von Daten keine Trigger verwendet werden müssen, beim Erstellen SELECTder Daten keine Funktionen verwendet werden müssen und dass Sie jederzeit die zusätzlichen Nullen entfernen oder die Feldlänge erhöhen können du änderst deine Meinung.

Eine Axt
quelle
3
Unsigned Zerofill ist der richtige Weg, obwohl Smallint bei 65535 maximal ist. Ich würde Mediumint vorschlagen. Cali hat Reißverschlüsse von 9xxxx.
Brandon-Estrella-Dev
4
Wenn Sie jemals Postleitzahlen für andere Länder unterstützen möchten, möchten Sie keine Ganzzahl. Einige Länder verwenden Buchstaben in ihren Postleitzahlen.
Wodin
11

Ok, Sie haben also die Spalte von Number auf VARCHAR (5) umgestellt. Jetzt müssen Sie das Postleitzahlfeld aktualisieren, damit es links aufgefüllt wird. Das SQL dafür wäre:

UPDATE MyTable
SET ZipCode = LPAD( ZipCode, 5, '0' );

Dadurch werden alle Werte in der ZipCode-Spalte auf 5 Zeichen aufgefüllt und links '0' hinzugefügt.

Jetzt, da Sie alle Ihre alten Daten repariert haben, müssen Sie natürlich sicherstellen, dass Ihre neuen Daten auch mit Nullen aufgefüllt sind. Es gibt mehrere Denkschulen, wie man das richtig macht:

  • Behandeln Sie es in der Geschäftslogik der Anwendung. Vorteile: Datenbankunabhängige Lösung, bei der Sie nicht mehr über die Datenbank erfahren müssen. Nachteile: Muss überall, wo in die Datenbank geschrieben wird, in allen Anwendungen behandelt werden.

  • Behandeln Sie es mit einer gespeicherten Prozedur. Vorteile: Gespeicherte Prozeduren erzwingen Geschäftsregeln für alle Kunden. Nachteile: Gespeicherte Prozeduren sind komplizierter als einfache INSERT / UPDATE-Anweisungen und nicht so datenbankübergreifend portierbar. Ein nacktes INSERT / UPDATE kann weiterhin Daten einfügen, die nicht mit Nullen aufgefüllt sind.

  • Fassen Sie es mit einem Abzug an. Vorteile: Funktioniert für gespeicherte Prozeduren und bloße INSERT / UPDATE-Anweisungen. Nachteile: Am wenigsten tragbare Lösung. Langsamste Lösung. Auslöser können schwer zu finden sein.

In diesem Fall würde ich es auf Anwendungsebene (wenn überhaupt) und nicht auf Datenbankebene behandeln. Schließlich verwenden nicht alle Länder eine 5-stellige Postleitzahl (nicht einmal die USA - unsere Postleitzahlen sind tatsächlich Postleitzahl + 4 + 2: nnnnn-nnnn-nn) und einige erlauben sowohl Buchstaben als auch Ziffern. Es ist besser, NICHT zu versuchen, ein Datenformat zu erzwingen und gelegentliche Datenfehler zu akzeptieren, als zu verhindern, dass jemand den richtigen Wert eingibt, obwohl das Format nicht ganz Ihren Erwartungen entspricht.

Craig Trader
quelle
4

Ich weiß, dass dies gut nach dem OP ist. Eine Möglichkeit, mit der die Tabelle die Postleitzahldaten als vorzeichenlose INT speichert, aber mit Nullen angezeigt wird, ist wie folgt.

select LPAD(cast(zipcode_int as char), 5, '0') as zipcode from table;

Während dies die ursprünglichen Daten als INT beibehält und Speicherplatz sparen kann, muss der Server die Konvertierung von INT in CHAR für Sie durchführen. Dies kann in eine Ansicht geworfen werden und die Person, die diese Daten benötigt, kann dort gegen die Tabelle selbst geleitet werden.

lemming622
quelle
3

Es wäre immer noch sinnvoll, Ihr Postleitzahlfeld als nullgefülltes vorzeichenloses Ganzzahlfeld zu erstellen.

CREATE TABLE xxx ( zipcode INT(5) ZEROFILL UNSIGNED, ... )

Auf diese Weise kümmert sich MySQL für Sie um die Polsterung.

Peter
quelle
3
CHAR(5)

oder

MEDIUMINT (5) UNSIGNED ZEROFILL

Der erste benötigt 5 Bytes pro Postleitzahl.

Die zweite benötigt nur 3 Bytes pro Postleitzahl. Die Option ZEROFILL ist für Postleitzahlen mit führenden Nullen erforderlich.

Martin Sansone - MiOEE
quelle
3

Sie sollten UNSIGNED ZEROFILLin Ihrer Tabellenstruktur verwenden.

Saurabh Chandra Patel
quelle
0

LPAD funktioniert mit VARCHAR2, da keine Leerzeichen für übrig gebliebene Bytes eingefügt werden. LPAD ändert übrig gebliebene / Null-Bytes in Nullen im LHS SO-Datentyp sollte VARCHAR2 sein

Agent Mahone
quelle