2010-07-08 14 views
69

Nel mio database InnoDB MySQL, ho dati di codice postale sporchi che voglio pulire.MySQL: come applicare il codice postale sul pad con "0"?

I dati del codice postale puliti sono quando ho tutte le 5 cifre per un codice postale (ad esempio "90210").

Ma per qualche motivo, ho notato nel mio database che per i codici di avviamento postale che iniziano con uno "0", lo 0 è stato eliminato.

Così "Holtsville, New York" con codice postale "00544" viene memorizzato nel mio database come "544"

e

"Dedham, MA" con codice postale "02026" è memorizzata nel mio database come "2026".

Quale SQL è possibile eseguire sul front pad "0" su qualsiasi codice di avviamento postale che non sia di 5 cifre di lunghezza? Significato, se il codice di avviamento postale è di 3 cifre in lunghezza, pad anteriore "00". Se il codice di avviamento postale è di 4 cifre in lunghezza, il pannello frontale è solo "0".

UPDATE:

Ho appena cambiato il codice postale di essere tipo di dati VARCHAR (5)

+3

Sembra che la colonna della tabella per il codice postale sia di tipo Numero e causa il problema. In tal caso, è necessario modificare il tipo di dati per conservare i dati dei caratteri. – Kangkan

+1

@ Kangkan, hai ragione. Il mio tipo di dati era un numero. Ho appena convertito il codice postale in varchar (5). Ora, come andare in prima pagina TeddyR

+1

È preferibile utilizzare CHAR anziché VARCHAR. Aumenta le query di molto quando la tabella diventa grande (solo se tutte le altre colonne hanno dimensioni fisse) – quantumSoup

risposta

166

Memorizza i tuoi zipcodes come CHAR (5) invece di un tipo numerico, o che hanno l'applicazione pad con zeri quando lo si carica dal DB. Un modo per farlo con PHP usando sprintf():

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

Oppure si potrebbe avere MySQL pad per voi con LPAD():

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

Ecco un modo per aggiornare e pad tutte le righe:

ALTER TABLE `table` CHANGE `zip` `zip` CHAR(5); #changes type 
UPDATE table SET `zip`=LPAD(`zip`, 5, '0'); #pads everything 
+0

Mi piacerebbe effettivamente ripulire i miei dati nel database stesso. Conosci l'equivalente per farlo con SQL? – TeddyR

+1

@TeddyR Sì, controllare la risposta aggiornata^ – quantumSoup

+1

Ho eseguito il seguente codice che ha funzionato "UPDATE tablename SET zip = LPAD (zip, 5, '0');" – TeddyR

7

Ok, quindi hai cambiato la colonna da Numero a VARCHAR (5). Ora è necessario aggiornare il campo del codice postale in modo che venga lasciato a sinistra. L'SQL per farlo sarebbe:

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

Questo pad tutti i valori nella colonna ZipCode a 5 caratteri, aggiungendo '0 di sinistra.

Ovviamente, ora che tutti i vecchi dati sono stati corretti, è necessario assicurarsi che anche i nuovi dati siano riempiti a zero. Esistono diverse scuole di pensiero sul modo corretto di farlo:

  • Gestirlo nella business logic dell'applicazione. Vantaggi: la soluzione indipendente dal database, non comporta l'apprendimento di più sul database. Svantaggi: deve essere gestito ovunque che scrive nel database, in tutte le applicazioni.

  • Gestirlo con una procedura memorizzata. Vantaggi: le stored procedure applicano le regole aziendali per tutti i client. Svantaggi: le stored procedure sono più complicate delle semplici istruzioni INSERT/UPDATE e non sono così portabili tra i database. Un INSERIMENTO/AGGIORNAMENTO nullo può ancora inserire dati non azzerati.

  • Gestirlo con un grilletto.Vantaggi: funzionerà per stored procedure e dichiarazioni INSERT/UPDATE nulle. Svantaggi: soluzione meno portatile. Soluzione più lenta I trigger possono essere difficili da ottenere.

In questo caso, lo gestisco a livello di applicazione (se non del tutto), e non a livello di database. Dopo tutto, non tutti i paesi usano un codice postale a 5 cifre (nemmeno gli Stati Uniti - i nostri codici di avviamento postale sono in realtà Zip + 4 + 2: nnnnn-nnnn-nn) e alcuni permettono lettere e cifre. Meglio NON provare e forzare un formato dati e accettare l'errore occasionale dei dati, piuttosto che impedire a qualcuno di inserire il valore corretto, anche se il formato non è esattamente quello che ci si aspettava.

+1

+1: questo mi ha aiutato nel mio caso specifico, dove stavo facendo un esercizio di purificazione dei dati esclusivamente in SQL (i dati importati da una terza parte avevano gli zeri iniziali mancanti, quindi ho dovuto risolvere) – SDC

16

È necessario decidere la lunghezza del codice postale (che credo dovrebbe essere lungo 5 caratteri). Quindi devi dire a MySQL di riempire a zero i numeri.

Supponiamo che il tuo tavolo si chiami mytable e che il campo in questione sia zipcode, tipo smallint. È necessario eseguire la seguente query:

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

Il vantaggio di questo metodo è che lascia i tuoi dati intatti, non c'è alcuna necessità di utilizzare i trigger durante l'inserimento dei dati/aggiornamenti, non c'è bisogno di usare le funzioni quando si SELECT i dati e che puoi sempre rimuovere gli zeri in più o aumentare la lunghezza del campo se dovessi cambiare idea.

+2

Zerofill senza firma è il modo andare, anche se smallint raggiunge il massimo a 65535. Suggerirei un mezzo. Cali ha le zip di 9xxxx. –

+3

Se si desidera supportare i codici postali per altri paesi, non si desidera un numero intero. Alcuni paesi usano lettere nei loro codici postali. – Wodin

3

Avrebbe ancora senso creare il campo del codice postale come campo intero senza segno con zerofilled.

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

In questo modo mysql si prende cura delle imbottiture per voi.

3
CHAR(5) 

o

MEDIUMINT (5) UNSIGNED ZEROFILL 

Il primo si 5 byte per codice postale.

Il secondo richiede solo 3 byte per codice di avviamento postale. L'opzione ZEROFILL è necessaria per i codici postali con zero iniziali.

0

LPAD funziona con VARCHAR2 in quanto non inserisce spazi per byte di sinistra. LPAD cambia rimanenti byte/null a zeri sul LHS SO tipo di dati dovrebbe essere VARCHAR2

3

si dovrebbe usare UNSIGNED ZEROFILL nella struttura della tabella.

Problemi correlati