MySQL - comment remplir le code postal avec «0»?

89

Dans ma base de données MySQL InnoDB, j'ai des données de code postal sales que je veux nettoyer.

Les données de code postal propres sont lorsque j'ai les 5 chiffres pour un code postal (par exemple "90210").

Mais pour une raison quelconque, j'ai remarqué dans ma base de données que pour les codes zip qui commencent par un "0", le 0 a été abandonné.

Donc " Holtsville, New York " avec le code postal " 00544" est stocké dans ma base de données sous " 544"

et

" Dedham, MA " avec le code postal " 02026" est stocké dans ma base de données sous le nom " 2026".

Quel SQL puis-je exécuter sur le pavé avant "0" vers un code postal qui ne comporte pas 5 chiffres? Cela signifie que si le code postal comporte 3 chiffres, le pavé avant "00". Si le code postal comporte 4 chiffres, le pavé avant est juste "0".

MISE À JOUR :

Je viens de changer le code postal pour qu'il soit de type de données VARCHAR (5)

TeddyR
la source
3
Il semble que la colonne de table pour le code postal soit de type Number et que cela pose problème. Dans ce cas, vous devrez changer le type de données pour conserver les données de caractères.
Kangkan
1
@Kangkan, vous avez raison. Mon type de données était un nombre. Je viens de convertir le code postal en varchar (5). Maintenant, comment aller sur la page d'accueil <5 codes postaux avec un "0"?
TeddyR
1
Il vaut mieux utiliser CHAR au lieu de VARCHAR. Cela accélérera beaucoup les requêtes lorsque la table deviendra grande (seulement si toutes vos autres colonnes ont une taille fixe)
QuantumSoup
2
Considérez également que les codes postaux d'autres pays ne sont pas toujours à 5 caractères.
Bill Karwin

Réponses:

214

Stockez vos codes postaux en tant que CHAR (5) au lieu d'un type numérique, ou demandez à votre application de le remplir avec des zéros lorsque vous le chargez à partir de la base de données. Une façon de le faire avec PHP en utilisant sprintf():

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

Ou vous pouvez demander à MySQL de le remplir pour vous avec LPAD():

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

Voici un moyen de mettre à jour et de remplir toutes les lignes:

ALTER TABLE `table` CHANGE `zip` `zip` CHAR(5); #changes type
UPDATE table SET `zip`=LPAD(`zip`, 5, '0'); #pads everything
quantumSoup
la source
Je voudrais réellement nettoyer mes données dans la base de données elle-même. Connaissez-vous l'équivalent pour faire cela avec SQL?
TeddyR
1
J'ai exécuté le code suivant qui l'a fait fonctionner "UPDATE tablename SET zip = LPAD (zip, 5, '0');"
TeddyR
Je dirais que cette réponse «acceptée» n'est pas aussi bonne que les ZEROFILLréponses.
Rick James le
Un défaut dans cette réponse. Si la valeur par défaut CHARACTER SETest utf8, cela CHAR(5)prendra inutilement 15 octets!
Rick James le
19

Vous devez décider de la longueur du code postal (qui, je crois, devrait contenir 5 caractères). Ensuite, vous devez dire à MySQL de remplir les nombres à zéro.

Supposons que votre table soit appelée mytableet que le champ en question soit zipcode, type smallint. Vous devez émettre la requête suivante:

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

L'avantage de cette méthode est qu'elle laisse vos données intactes, il n'est pas nécessaire d'utiliser des déclencheurs lors de l'insertion / mise à jour des données, il n'est pas nécessaire d'utiliser des fonctions lorsque vous utilisez SELECTles données et que vous pouvez toujours supprimer les zéros supplémentaires ou augmenter la longueur du champ. vous changez d'avis.

Anax
la source
3
Zerofill non signé est la voie à suivre, bien que smallint atteigne 65535. Je suggérerais mediumint. Cali a des zips de 9xxxx.
brandon-estrella-dev
4
Si jamais vous souhaitez prendre en charge les codes postaux pour d'autres pays, vous ne voulez pas d'entier. Certains pays utilisent des lettres dans leurs codes postaux.
Wodin le
11

Ok, donc vous avez changé la colonne de Number à VARCHAR (5). Vous devez maintenant mettre à jour le champ du code postal pour qu'il soit rempli à gauche. Le SQL pour faire cela serait:

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

Cela remplira toutes les valeurs de la colonne ZipCode à 5 caractères, en ajoutant des «0» sur la gauche.

Bien sûr, maintenant que toutes vos anciennes données sont corrigées, vous devez vous assurer que vos nouvelles données sont également remplies de zéro. Il existe plusieurs écoles de pensée sur la bonne façon de procéder:

  • Gérez-le dans la logique métier de l'application. Avantages: solution indépendante de la base de données, n'implique pas d'en savoir plus sur la base de données. Inconvénients: doit être manipulé partout où écrit dans la base de données, dans toutes les applications.

  • Traitez-le avec une procédure stockée. Avantages: les procédures stockées appliquent les règles métier pour tous les clients. Inconvénients: les procédures stockées sont plus compliquées que les simples instructions INSERT / UPDATE et ne sont pas aussi portables entre les bases de données. Un INSERT / UPDATE nu peut toujours insérer des données non complétées par zéro.

  • Manipulez-le avec une gâchette. Avantages: fonctionnera pour les procédures stockées et les instructions INSERT / UPDATE nues. Inconvénients: Solution la moins portable. Solution la plus lente. Les déclencheurs peuvent être difficiles à obtenir.

Dans ce cas, je le gérerais au niveau de l'application (voire pas du tout), et non au niveau de la base de données. Après tout, tous les pays n'utilisent pas un code postal à 5 ​​chiffres (pas même les États-Unis - nos codes postaux sont en fait Zip + 4 + 2: nnnnn-nnnn-nn) et certains autorisent les lettres ainsi que les chiffres. Mieux vaut NE PAS essayer de forcer un format de données et d'accepter l'erreur de données occasionnelle, que d'empêcher quelqu'un d'entrer la valeur correcte, même si son format n'est pas tout à fait ce que vous attendiez.

Craig Trader
la source
4

Je sais que c'est bien après l'OP. Une façon que vous pouvez utiliser qui garde la table stockant les données de code postal en tant qu'INT non signé mais affichée avec des zéros est la suivante.

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

Bien que cela préserve les données d'origine en tant qu'INT et puisse économiser de l'espace de stockage, le serveur effectuera la conversion INT en CHAR pour vous. Cela peut être jeté dans une vue et la personne qui a besoin de ces données peut être dirigée vers la table elle-même.

lemming622
la source
3

Il serait toujours judicieux de créer votre champ de code postal sous la forme d'un champ entier non signé rempli de zéros.

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

De cette façon, mysql s'occupe du remplissage pour vous.

Peter
la source
3
CHAR(5)

ou

MEDIUMINT (5) UNSIGNED ZEROFILL

Le premier prend 5 octets par code postal.

Le second ne prend que 3 octets par code postal. L'option ZEROFILL est nécessaire pour les codes postaux avec des zéros non significatifs.

Martin Sansone - MiOEE
la source
3

vous devez utiliser UNSIGNED ZEROFILLdans votre structure de table.

Saurabh Chandra Patel
la source
0

LPAD fonctionne avec VARCHAR2 car il ne met pas d'espaces pour les octets restants. LPAD remplace les octets restants / nuls par des zéros sur le type de données LHS SO doit être VARCHAR2

Agent Mahone
la source