MySQL - як вставити поштовий індекс на "0"?


93

У базі даних MySQL InnoDB у мене є брудні дані поштового індексу, які я хочу очистити.

Чисті дані поштового індексу - це коли у мене є всі 5 цифр для поштового індексу (наприклад, "90210").

Але з якоїсь причини я помітив у своїй базі даних, що для поштових індексів, які починаються з "0", значення 0 було відкинуто.

Тож " Holtsville, New York " з поштовим індексом " 00544" зберігається в моїй базі даних як " 544"

і

" Dedham, MA " з поштовим індексом " 02026" зберігається в моїй базі даних як " 2026".

Який SQL я можу запустити на передню панель "0" до будь-якого поштового індексу, який не має 5 цифр? Це означає, що якщо поштовий індекс має 3 цифри, передня панель "00". Якщо поштовий індекс довжиною 4 цифри, передня панель просто "0".

ОНОВЛЕННЯ :

Я щойно змінив поштовий індекс на тип даних VARCHAR (5)


3
Здається, стовпець таблиці для поштового індексу має тип Number і це спричиняє проблему. У цьому випадку вам доведеться змінити тип даних, щоб зберегти символьні дані.
Кангкан

1
@Kangkan, ти маєш рацію. Моїм типом даних було число. Я щойно перетворив поштовий індекс на varchar (5). Тепер, як перейти на головну сторінку <5-значні поштові індекси з "0"?
TeddyR

1
Краще використовувати CHAR замість VARCHAR. Це значно прискорить запити, коли таблиця стане великою (лише якщо всі ваші інші стовпці мають фіксований розмір)
quantumSoup

2
Також враховуйте, що поштові індекси з інших країн не завжди складають 5 символів.
Білл Карвін,

Відповіді:


219

Зберігайте свої поштові індекси як CHAR (5), а не числовий тип, або під час завантаження з БД додаток додайте до нього нулі. Спосіб зробити це за допомогою PHP за допомогою sprintf():

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

Або ви можете підключити MySQL до себе за допомогою LPAD():

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

Ось спосіб оновити та заповнити всі рядки:

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

Я хотів би фактично очистити свої дані в самій базі даних. Чи знаєте ви еквівалент, щоб зробити це з SQL?
TeddyR

1
Я запустив такий код, який змусив його працювати "ОНОВИТИ назву таблиці SET zip = LPAD (zip, 5, '0');"
TeddyR

Я б стверджував, що ця "прийнята" відповідь не така хороша, як ZEROFILLвідповіді.
Rick James

Вада у цій відповіді. Якщо за замовчуванням CHARACTER SETutf8, це CHAR(5)займе 15 байт!
Rick James

19

Вам потрібно визначити довжину поштового індексу (яка, на мою думку, повинна складати 5 символів). Потім вам потрібно сказати MySQL, щоб нуль не заповнював числа.

Припустимо, ваша таблиця викликається, mytableа поле, про яке йдеться, - zipcodeтип smallint. Вам потрібно виконати такий запит:

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

Перевага цього методу полягає в тому, що він залишає ваші дані недоторканими, немає необхідності використовувати тригери під час вставки / оновлення даних, немає необхідності використовувати функції, коли ви SELECTпередаєте дані, і що ви завжди можете видалити зайві нулі або збільшити довжину поля, якщо ви передумаєте.


3
Непідписаний Zerofill - це шлях, хоча smallint перевищує 65535. Я б запропонував mediumint. Калі має застібки 9xxxx.
brandon-estrella-dev

4
Якщо ви коли-небудь захочете підтримувати поштові індекси для інших країн, ви не хочете цілого числа. Деякі країни використовують літери у своїх поштових індексах.
Водін,

12

Гаразд, отже, ви переключили стовпець з Number на VARCHAR (5). Тепер вам потрібно оновити поле поштового індексу, щоб воно було заповнено лівим. SQL для цього мав би бути:

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

Це заповнить усі значення у стовпці ZipCode 5 символами, додавши 0 зліва.

Звичайно, тепер, коли ви виправили всі свої старі дані, вам потрібно переконатись, що будь-які нові дані також мають нульовий відступ. Існує декілька шкіл думок, як правильно це зробити:

  • Обробляйте це в бізнес-логіці програми. Переваги: ​​рішення, незалежне від бази даних, не передбачає дізнання більше про базу даних. Недоліки: потрібно обробляти скрізь, що пише в базу даних, у всіх додатках.

  • Обробляйте це за допомогою збереженої процедури. Переваги: ​​Збережені процедури забезпечують ділові правила для всіх клієнтів. Недоліки: збережені процедури складніші, ніж прості оператори INSERT / UPDATE, і не такі портативні в базах даних. Голі ВСТАВКИ / ОНОВЛЕННЯ все ще можуть вставляти дані, не заповнені нулем.

  • Обробляйте його спусковим гачком. Переваги: ​​Працюватиме для збережених процедур та оголених операторів INSERT / UPDATE. Недоліки: Найменш портативне рішення. Найповільніше рішення. Тригери важко отримати правильно.

У цьому випадку я б обробляв це на рівні програми (якщо взагалі), а не на рівні бази даних. Зрештою, не у всіх країнах використовується 5-значний поштовий індекс (навіть у США - наші поштові індекси насправді є Zip + 4 + 2: nnnnn-nnnn-nn), а деякі дозволяють використовувати букви, а також цифри. Краще НЕ намагатися змусити формат даних та приймати випадкові помилки даних, ніж заважати комусь вводити правильне значення, хоча це не зовсім те, що ви очікували.


4

Я знаю, що це вже після ОП. Один із способів, з яким ви можете піти: таблиця зберігає дані поштового індексу у вигляді беззнакового INT, але відображається нулями, як показано нижче.

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

Хоча це зберігає вихідні дані як INT і може заощадити трохи місця в сховищі, ви будете мати, щоб сервер виконував для вас перетворення INT у CHAR. Це може бути кинуто в поле зору, і людина, якій потрібні ці дані, може бути спрямована туди проти самої таблиці.


3

Все одно має сенс створити поле з поштовим індексом як ціле поле без підпису з нулем.

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

Таким чином mysql піклується про заповнення для вас.


3
CHAR(5)

або

MEDIUMINT (5) UNSIGNED ZEROFILL

Перший займає 5 байт на поштовий індекс.

Другий займає лише 3 байти на поштовий індекс. Опція ZEROFILL необхідна для поштових індексів із початковими нулями.



0

LPAD працює з VARCHAR2, оскільки не ставить пробіли для залишку байтів. LPAD змінює залишки / нульові байти на нулі для типу даних LHS SO повинен бути VARCHAR2

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.