MySQL-如何在邮政编码前面加上“ 0”?


89

在我的MySQL InnoDB数据库中,我要清除的邮政编码数据很脏。

干净的邮政编码数据是指我的邮政编码全5位(例如“ 90210”)。

但是由于某种原因,我在数据库中注意到对于以“ 0”开头的邮政编码,0已被删除。

因此,“ 纽约Holtsville的 ”与邮政编码“ 00544”存储在我的数据库“ 544

戴德姆,MA ”与邮政编码“ 02026”存储在我的数据库为“ 2026”。

我可以使用哪种SQL在长度不为5位的任何邮政编码前面填充“ 0”?意思是,如果邮政编码的长度为3位,则前面板为“ 00”。如果邮政编码的长度为4位,则前面板仅为“ 0”。

更新

我只是将邮政编码更改为数据类型VARCHAR(5)


3
似乎邮政编码的表列的类型为Number,这就是造成此问题的原因。在这种情况下,您必须更改数据类型以保留字符数据。
康坎2010年

1
@Kangkan,你是对的。我的数据类型是数字。我只是将邮政编码转换为varchar(5)。现在,如何去首页<5位邮政编码加上“ 0”?
TeddyR

1
最好使用CHAR而不是VARCHAR。当表变大时,它将大大加快查询速度(仅当您所有其他列的大小都固定时)
QuantumSoup 2010年

2
还应考虑其他国家的邮政编码并非总是5个字符。
Bill Karwin

Answers:


214

将您的邮政编码存储为CHAR(5)而不是数字类型,或者从DB加载时将其填充为零。一种使用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
我运行了使它起作用的以下代码“ UPDATE tablename SET zip = LPAD(zip,5,'0');”
TeddyR

我认为这个“接受的”答案不如ZEROFILL答案。
瑞克·詹姆斯

这个答案有缺陷。如果默认CHARACTER SET值为utf8,CHAR(5)则将不必要地占用15个字节!
瑞克·詹姆斯

19

您需要确定邮政编码的长度(我认为应该为5个字符长)。然后,您需要告诉MySQL将数字零填充。

假设您的表被调用mytable,所涉及的字段为zipcodetype smallint。您需要发出以下查询:

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

这种方法的优点是它使您的数据保持完整,在数据插入/更新过程中无需使用触发器,在数据使用时不需要使用函数,SELECT并且始终可以删除多余的零或增加字段长度。你改变主意。


3
未签名的Zerofill是可行的方法,尽管smallint的最大值为65535。我建议选择mediumint。卡利的邮编为9xxxx。
brandon-estrella-dev

4
如果您想支持其他国家的邮政编码,则不需要整数。一些国家在其邮政编码中使用字母。
Wodin

11

好的,因此您已将列从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

我知道OP之后就很好。可以使用的一种方法是,将存储邮政编码数据的表保持为无符号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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.