MySQL - come inserire in primo piano il codice postale con "0"?


89

Nel mio database MySQL InnoDB, ho dei dati di codice postale sporchi che voglio pulire.

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

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

Quindi " Holtsville, New York " con codice postale " 00544" è memorizzato nel mio database come " 544"

e

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

Quale SQL posso eseguire sul pad anteriore "0" per qualsiasi codice postale che non sia di 5 cifre? Significato, se il codice postale è di 3 cifre, il pad anteriore è "00". Se il codice postale è di 4 cifre, il pad anteriore è solo "0".

AGGIORNAMENTO :

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


3
Sembra che la colonna della tabella per il codice postale sia di tipo Numero e questo sta causando il problema. In tal caso, sarà necessario modificare il tipo di dati per mantenere 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 portare in prima pagina i codici postali a 5 cifre con uno "0"?
TeddyR

1
È meglio usare CHAR invece di VARCHAR.
Accelererà di

2
Considera anche che i codici postali di altri paesi non sono sempre di 5 caratteri.
Bill Karwin

Risposte:


214

Memorizza i tuoi codici postali come CHAR (5) invece di un tipo numerico, o fai in modo che la tua applicazione li riempia di zero quando la carichi dal DB. Un modo per farlo con PHP usando sprintf():

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

Oppure potresti fare in modo che MySQL lo riempia per te con LPAD():

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

Ecco un modo per aggiornare e riempire tutte le righe:

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

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

1
Ho eseguito il codice seguente che lo ha fatto funzionare "UPDATE tablename SET zip = LPAD (zip, 5, '0');"
TeddyR

Direi che questa risposta "accettata" non è buona quanto le ZEROFILLrisposte.
Rick James

Un difetto in questa risposta. Se il valore predefinito CHARACTER SETè utf8, CHAR(5)ci vorranno 15 byte inutilmente!
Rick James

19

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

Supponiamo che la tua tabella venga chiamata mytablee il campo in questione sia zipcodetipo smallint. È necessario emettere la seguente query:

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

Il vantaggio di questo metodo è che lascia i dati intatti, non è necessario utilizzare trigger durante l'inserimento / aggiornamento dei dati, non è necessario utilizzare le funzioni quando si SELECTinseriscono i dati e che è sempre possibile rimuovere gli zeri extra o aumentare la lunghezza del campo cambi idea.


3
Zerofill non firmato è la strada da percorrere, anche se smallint arriva al massimo a 65535. Suggerirei mediumint. Cali ha zip di 9xxxx.
brandon-estrella-dev

4
Se vuoi supportare i codici postali per altri paesi, non vuoi un numero intero. Alcuni paesi utilizzano lettere nei codici postali.
Wodin

11

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

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

Questo riempirà tutti i valori nella colonna ZipCode a 5 caratteri, aggiungendo "0" a sinistra.

Ovviamente, ora che hai sistemato tutti i tuoi vecchi dati, devi assicurarti che anche i tuoi nuovi dati siano a riempimento zero. Esistono diverse scuole di pensiero sul modo corretto di farlo:

  • Gestiscilo nella logica di business dell'applicazione. Vantaggi: soluzione indipendente dal database, non implica l'apprendimento di più sul database. Svantaggi: deve essere gestito ovunque si scriva nel database, in tutte le applicazioni.

  • Gestiscilo con una procedura memorizzata. Vantaggi: le procedure memorizzate applicano le regole di business per tutti i clienti. Svantaggi: le stored procedure sono più complicate delle semplici istruzioni INSERT / UPDATE e non sono portabili tra i database. Un semplice INSERT / UPDATE può ancora inserire dati con riempimento diverso da zero.

  • Gestiscilo con un grilletto. Vantaggi: funzionerà per le stored procedure e le istruzioni INSERT / UPDATE nude. Svantaggi: soluzione meno portatile. Soluzione più lenta. I trigger possono essere difficili da ottenere correttamente.

In questo caso, lo gestirò a livello di applicazione (se non del tutto) e non a livello di database. Dopotutto, non tutti i paesi utilizzano un codice postale di 5 cifre (nemmeno gli Stati Uniti - i nostri codici postali sono in realtà Zip + 4 + 2: nnnnn-nnnn-nn) e alcuni consentono lettere e cifre. Meglio NON provare a 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 ti aspettavi.


4

So che questo è ben dopo l'OP. Un modo in cui puoi procedere che mantiene la tabella che memorizza i dati del codice postale come INT non firmato ma visualizzato con zeri è il seguente.

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

Anche se questo preserva i dati originali come INT e può risparmiare spazio nell'archiviazione, il server eseguirà la conversione da INT a CHAR per te. Questo può essere lanciato in una vista e la persona che ha bisogno di questi dati può essere indirizzata lì contro la tabella stessa.


3

Avrebbe comunque senso creare il campo del codice postale come un campo intero non firmato con zero.

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

In questo modo mysql si prende cura dell'imbottitura per te.


3
CHAR(5)

o

MEDIUMINT (5) UNSIGNED ZEROFILL

Il primo richiede 5 byte per codice postale.

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



0

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.