在我的MySQL InnoDB数据库中,我有要清理的脏邮政编码数据。
干净的邮政编码数据是指邮政编码的所有5位数字(例如“90210”)。
但出于某种原因,我注意到在我的数据库中,对于以“0”开头的zipcodes,0已被删除。
所以“纽约州霍尔茨维尔”邮编“00544
”在我的数据库中存储为“544
”
和
带有邮政编码“02026
”的“ Dedham,MA ”在我的数据库中存储为“2026
”。
对于任何长度不是5位的邮政编码,我可以运行哪些SQL来填充“0”前缀?意思是,如果邮政编码长度为3位,则前垫“00”。如果邮政编码的长度为4位,则前垫仅为“0”。
更新:
我刚刚将zipcode更改为数据类型VARCHAR(5)
答案 0 :(得分:193)
将您的邮政编码存储为CHAR(5)而不是数字类型,或者在从数据库加载时将应用程序填充为零。使用sprintf()
进行PHP的方法:
echo sprintf("%05d", 205); // prints 00205
echo sprintf("%05d", 1492); // prints 01492
或者你可以使用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
答案 1 :(得分:16)
您需要确定邮政编码的长度(我认为邮政编码长度应为5个字符)。然后你需要告诉MySQL零填充数字。
我们假设您的表名为mytable
,相关字段为zipcode
,类型为smallint
。您需要发出以下查询:
ALTER TABLE mytable CHANGE `zipcode` `zipcode`
MEDIUMINT( 5 ) UNSIGNED ZEROFILL NOT NULL;
这种方法的优点是它可以保持数据的完整性,在数据插入/更新过程中不需要使用触发器,在SELECT
数据时不需要使用函数,并且可以随时删除如果你改变主意,可以额外加零或增加场长。
答案 2 :(得分:10)
好的,所以你已经将列从Number切换到VARCHAR(5)。现在您需要更新要填充的zipcode字段。执行此操作的SQL将是:
UPDATE MyTable
SET ZipCode = LPAD( ZipCode, 5, '0' );
这会将ZipCode列中的所有值填充为5个字符,并在左侧添加“0”。
当然,现在你已经修复了所有旧数据,你需要确保你的任何新数据都是零填充的。关于正确的方法,有几种思想流派:
在应用程序的业务逻辑中处理它。优点:独立于数据库的解决方案,不涉及更多地了解数据库。缺点:需要在所有应用程序中处理写入数据库的所有位置。
使用存储过程处理它。优点:存储过程为所有客户端强制执行业务规则。缺点:存储过程比简单的INSERT / UPDATE语句更复杂,而不是跨数据库可移植。裸INSERT / UPDATE仍然可以插入非零填充数据。
使用触发器处理它。优点:适用于存储过程和裸INSERT / UPDATE语句。缺点:最便携的解决方案。最慢的解决方案。触发器很难做到正确。
在这种情况下,我会在应用程序级别(如果有的话)处理它,而不是数据库级别。毕竟,并非所有国家/地区都使用5位数的Zipcode(甚至不是美国 - 我们的邮政编码实际上是Zip + 4 + 2:nnnnn-nnnn-nn),有些还允许使用字母和数字。最好不要试图强制数据格式并接受偶尔的数据错误,而不是阻止某人输入正确的值,即使它的格式不是您所期望的。
答案 3 :(得分:3)
将邮政编码字段创建为零填充无符号整数字段仍然有意义。
CREATE TABLE xxx (
zipcode INT(5) ZEROFILL UNSIGNED,
...
)
这样mysql会为你处理填充。
答案 4 :(得分:3)
CHAR(5)
或
MEDIUMINT (5) UNSIGNED ZEROFILL
第一个每个邮政编码需要5个字节。
第二个邮政编码只需3个字节。对于带有前导零的邮政编码,ZEROFILL选项是必需的。
答案 5 :(得分:3)
您应该在表格结构中使用UNSIGNED ZEROFILL
。
答案 6 :(得分:3)
我知道在OP之后这很好。你可以采用的一种方法是将表格存储的zipcode数据保存为无符号INT,但用零显示如下。
select LPAD(cast(zipcode_int as char), 5, '0') as zipcode from table;
虽然这会将原始数据保留为INT并且可以在存储中节省一些空间,但您将让服务器为您执行INT到CHAR转换。这可以被抛到一个视图中,需要这些数据的人可以指向那里与表本身。
答案 7 :(得分:0)
LPAD与VARCHAR2一起使用,因为它没有为字节留下空格。 LPAD将LFS上的剩余/空字节更改为零 SO数据类型应为VARCHAR2