MySQL - ¿cómo colocar el código postal de la almohadilla frontal con "0"?

93

En mi base de datos MySQL InnoDB, tengo datos de códigos postales sucios que quiero limpiar.

Los datos del código postal limpio son cuando tengo los 5 dígitos para un código postal (por ejemplo, "90210").

Pero por alguna razón, noté en mi base de datos que para los códigos postales que comienzan con un "0", el 0 se ha eliminado.

Entonces, " Holtsville, Nueva York " con código postal " 00544" se almacena en mi base de datos como "544 "

y

" Dedham, MA " con código postal " 02026" se almacena en mi base de datos como "2026 ".

¿Qué SQL puedo ejecutar en el panel frontal "0" de cualquier código postal que no tenga 5 dígitos de longitud? Es decir, si el código postal tiene 3 dígitos, el panel frontal es "00". Si el código postal tiene 4 dígitos, el panel frontal solo tiene "0".

ACTUALIZAR :

Acabo de cambiar el código postal para que sea el tipo de datos VARCHAR (5)

TeddyR
fuente
3
Parece que la columna de la tabla para el código postal es de tipo Número y eso está causando el problema. En ese caso, deberá cambiar el tipo de datos para mantener los datos de los caracteres.
Kangkan
1
@Kangkan, tienes razón. Mi tipo de datos era un número. Acabo de convertir el código postal a varchar (5). Ahora, ¿cómo ir a la página principal <códigos postales de 5 dígitos con un "0"?
TeddyR
1
Es mejor usar CHAR en lugar de VARCHAR.
Acelerará
2
También considere que los códigos postales de otros países no siempre son de 5 caracteres.
Bill Karwin

Respuestas:

219

Almacene sus códigos postales como CHAR (5) en lugar de un tipo numérico, o haga que su aplicación lo rellene con ceros cuando lo cargue desde la base de datos. Una forma de hacerlo con PHP usando sprintf():

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

O podría tener MySQL pad para usted con LPAD():

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

Aquí hay una forma de actualizar y rellenar todas las filas:

ALTER TABLE `table` CHANGE `zip` `zip` CHAR(5); #changes type
UPDATE table SET `zip`=LPAD(`zip`, 5, '0'); #pads everything
QuantumSoup
fuente
Me gustaría realmente limpiar mis datos en la propia base de datos. ¿Conoce el equivalente a hacer esto con SQL?
TeddyR
1
Ejecuté el siguiente código que lo hizo funcionar "UPDATE tablename SET zip = LPAD (zip, 5, '0');"
TeddyR
Yo diría que esta respuesta 'aceptada' no es tan buena como las ZEROFILLrespuestas.
Rick James
Un defecto en esta respuesta. Si el valor predeterminado CHARACTER SETes utf8, ¡eso CHAR(5)tomará 15 bytes innecesariamente!
Rick James
19

Debe decidir la longitud del código postal (que creo que debería tener 5 caracteres). Luego, debe decirle a MySQL que complete los números con cero.

Supongamos que se llama a su tabla mytabley el campo en cuestión es zipcode, escribasmallint . Debe realizar la siguiente consulta:

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

La ventaja de este método es que deja sus datos intactos, no hay necesidad de usar activadores durante la inserción / actualización de datos, no hay necesidad de usar funciones cuando se obtienen SELECTlos datos y que siempre puede eliminar los ceros adicionales o aumentar la longitud del campo. cambia tu forma de pensar.

Un hacha
fuente
3
Zerofill sin firmar es el camino a seguir, aunque smallint alcanza un máximo de 65535. Sugeriría mediumint. Cali tiene cremalleras de 9xxxx.
brandon-estrella-dev
4
Si alguna vez desea admitir códigos postales de otros países, no desea un número entero. Algunos países utilizan letras en sus códigos postales.
Wodin
12

Bien, entonces ha cambiado la columna de Número a VARCHAR (5). Ahora necesita actualizar el campo del código postal para que se rellene a la izquierda. El SQL para hacer eso sería:

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

Esto rellenará todos los valores en la columna ZipCode a 5 caracteres, agregando '0's a la izquierda.

Por supuesto, ahora que ha arreglado todos sus datos antiguos, debe asegurarse de que los datos nuevos también tengan un relleno de ceros. Hay varias escuelas de pensamiento sobre la forma correcta de hacerlo:

  • Manejarlo en la lógica empresarial de la aplicación. Ventajas: solución independiente de la base de datos, no implica aprender más sobre la base de datos. Desventajas: debe manejarse en todos los lugares donde se escribe en la base de datos, en todas las aplicaciones.

  • Manéjelo con un procedimiento almacenado. Ventajas: Los procedimientos almacenados hacen cumplir las reglas comerciales para todos los clientes. Desventajas: Los procedimientos almacenados son más complicados que las simples declaraciones INSERT / UPDATE y no son tan portables entre bases de datos. Un INSERT / UPDATE simple aún puede insertar datos sin relleno de ceros.

  • Manéjelo con un gatillo. Ventajas: funcionará para procedimientos almacenados y declaraciones INSERT / UPDATE desnudas. Desventajas: Solución menos portátil. Solución más lenta. Los desencadenantes pueden ser difíciles de acertar.

En este caso, lo manejaría a nivel de aplicación (si es que lo hace), y no a nivel de base de datos. Después de todo, no todos los países usan un código postal de 5 dígitos (ni siquiera los EE. UU., Nuestros códigos postales son en realidad Zip + 4 + 2: nnnnn-nnnn-nn) y algunos permiten letras y dígitos. Es mejor NO intentar forzar un formato de datos y aceptar el error de datos ocasional, que evitar que alguien ingrese el valor correcto, aunque el formato no sea el esperado.

Craig comerciante
fuente
4

Sé que esto es mucho después del OP. Una forma en la que puede seguir manteniendo la tabla almacenando los datos del código postal como un INT sin firmar pero que se muestra con ceros es la siguiente.

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

Si bien esto conserva los datos originales como INT y puede ahorrar algo de espacio en el almacenamiento, el servidor realizará la conversión de INT a CHAR por usted. Esto se puede mostrar en una vista y la persona que necesita estos datos puede dirigirse allí frente a la tabla en sí.

lemming622
fuente
3

Todavía tendría sentido crear su campo de código postal como un campo de entero sin firmar relleno cero.

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

De esa manera mysql se encarga del relleno por usted.

Pedro
fuente
3
CHAR(5)

o

MEDIUMINT (5) UNSIGNED ZEROFILL

El primero ocupa 5 bytes por código postal.

El segundo toma solo 3 bytes por código postal. La opción ZEROFILL es necesaria para códigos postales con ceros a la izquierda.

Martin Sansone - MiOEE
fuente
3

debe utilizar UNSIGNED ZEROFILLen la estructura de su tabla.

Saurabh Chandra Patel
fuente
0

LPAD trabaja con VARCHAR2 ya que no pone espacios para los bytes restantes. LPAD cambia los bytes restantes / nulos a ceros en el tipo de datos LHS SO debe ser VARCHAR2

Agente Mahone
fuente