MySQL - как поставить почтовый индекс на передней панели с «0»?


93

В моей базе данных MySQL InnoDB у меня есть грязные данные почтового индекса, которые я хочу очистить.

Чистые данные почтового индекса - это когда у меня есть все 5 цифр для почтового индекса (например, «90210»).

Но по какой-то причине я заметил в своей базе данных, что для почтовых индексов, начинающихся с «0», 0 был опущен.

Итак, " Холтсвилл, Нью-Йорк " с почтовым индексом " 00544" хранится в моей базе данных как " 544"

а также

" Dedham, MA " с почтовым индексом " 02026" хранится в моей базе данных как " 2026".

Какой SQL я могу запустить до "0" на передней панели любого почтового индекса, длина которого не превышает 5 цифр? Это означает, что если почтовый индекс состоит из 3 цифр, на передней панели «00». Если почтовый индекс состоит из 4 цифр, на передней панели просто «0».

ОБНОВЛЕНИЕ :

Я просто изменил почтовый индекс на тип данных VARCHAR (5)


3
Кажется, что столбец таблицы для почтового индекса имеет тип Number, и это вызывает проблему. В этом случае вам придется изменить тип данных, чтобы сохранить символьные данные.
Кангкан

1
@ Кангкан, ты прав. Моим типом данных было число. Я только что преобразовал почтовый индекс в varchar (5). Теперь, как перейти на главную страницу <5-значные почтовые индексы с "0"?
TeddyR 08

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 08

1
Я запустил следующий код, который заставил его работать: «UPDATE tablename SET zip = LPAD (zip, 5, '0');»
TeddyR 08

Я бы сказал, что этот «принятый» ответ не так хорош, как ZEROFILLответы.
Rick James

Ошибка в этом ответе. Если по умолчанию CHARACTER SETиспользуется utf8, это CHAR(5)займет 15 байт!
Rick James

19

Вам нужно определить длину почтового индекса (который, как мне кажется, должен составлять 5 символов). Затем вам нужно указать MySQL обнулить числа.

Предположим, ваша таблица вызывается, mytableа поле, о котором идет речь, - zipcodetype smallint. Вам необходимо отправить следующий запрос:

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

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


3
Неподписанный Zerofill - это то, что вам нужно, хотя smallint максимален на уровне 65535. Я бы посоветовал mediumint. У Кали есть молнии 9хххх.
brandon-estrella-dev

4
Если вы когда-нибудь захотите поддерживать почтовые индексы для других стран, вам не нужно целое число. Некоторые страны используют буквы в своих почтовых индексах.
Wodin

12

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

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

Это добавит все значения в столбце ZipCode к 5 символам, добавив слева «0».

Конечно, теперь, когда у вас есть все ваши старые данные, вам нужно убедиться, что все ваши новые данные также дополнены нулями. Есть несколько школ о том, как это сделать:

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

  • Обработайте это с помощью хранимой процедуры. Преимущества: хранимые процедуры обеспечивают соблюдение бизнес-правил для всех клиентов. Недостатки: хранимые процедуры сложнее простых операторов INSERT / UPDATE и не переносимы между базами данных. Пустой 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.