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.