为菜单/列表排序邮政编码

时间:2009-04-27 09:11:21

标签: sql sorting postal-code

我需要按顺序对英国邮政编码进行排序。

有一种简单的方法吗?

英国邮政编码由字母和数字组成:

查看格式的完整信息: http://en.wikipedia.org/wiki/UK_postcodes

但我的问题是这个简单的alpha排序不起作用,因为每个代码以1或2个字母开头,然后紧跟一个数字,最多两个数字,然后是一个空格,另一个数字,然后是一个字母。例如LS1 1AA或ls28 1AA,还有另一种情况,一旦第一部分的数字超过99,则继续9A等。

Alpha排序导致10s立即跟随1:

...
LS1 9ZZ
LS10 1AA
...
LS2 

我正在寻找创建一个SQL函数来将可打印的Postcode转换为可排序的邮政编码,例如'LS1 9ZZ'将成为'LS01 9ZZ',然后在order by子句中使用此功能。

是否有人这样或类似的事情已经完成了?

3 个答案:

答案 0 :(得分:4)

您需要将此视为标记化问题,因此SW1A 1AA应标记为:

  • SW
  • 1
  • A
  • 1AA

(尽管如果你愿意,你可以将内部部分分解为1和AA)

和G12 8QT应该标记为:

  • 12
  • (空字符串)
  • 8QT

一旦你将邮政编码分解成那些组成部分,那么排序应该很容易。 GIR 0AA邮政编码有一个例外,但您只需对该版本的测试进行硬编码即可。

编辑:关于标记化的更多想法

对于样本邮政编码SW1A 1AA,SW是邮政编码区域,1A是邮政编码区(我们将分为两部分进行分类),1是邮政编码扇区,AA是单位邮政编码。

这些是有效的邮政编码格式(来源:皇家邮政PAF用户指南第8页 - this page底部的链接):

AN NAA
AAN NAA
ANN NAA
ANA NAA
AAA NAA(仅适用于GIR 0AA代码)
AANN NAA
AANA NAA

所以粗略的算法就是(假设我们想要将扇区和单位邮政编码分开):

  • 代码= GIR 0AA? Tokenize to GI / R / / 0 / AA(将R视为区域简化了事情)
  • 代码5个字母长例如G1 3AF?标记为G / 1 / / 3 / AF
  • 代码6个字母长,第3个字符是字母,例如W1P 1HQ?标记为W / 1 / P / 1 / HQ
  • 代码6个字母长,第2个字符是字母,例如CR2 6XH?标记为CR / 2 / / 6 / XH
  • 代码7个字母长,第4个字符是字母,例如EC1A 1BB?标记为EC / 1 / A / 1 / BB
  • 否则例如TW14 2ZZ,标记为TW / 14 / / 2 / ZZ

如果目的是显示用户可供选择的邮政编码列表,那么我会采用Neil Butterworth的建议,即在数据库中存储邮政编码的“可排序”版本。创建可排序版本的最简单方法是将所有条目填充为九个字符:

  • 该区域有两个字符(如果更短,则为右键)
  • 两个用于区号(如果更短,则为左键)
  • 一个用于区域信件(垫子如果缺少)
  • 空间
  • 一个扇区
  • 两个单位

和GIR 0AA再次略有例外。如果使用空格填充,则排序顺序应该正确。使用#表示空格的示例:

  • W1#1AA => w ^ ## 1个## 1AA
  • WC1#1AA => WC#1 ## 1AA
  • W10#1AA => W#10 ## 1AA
  • W1W#1AA => w ^ ## 1W#1AA
  • GIR#0AA => GI# - [R ## 0AA
  • WC10#1AA => WC10 ## 1AA
  • WC1W#1AA => WC#1W#1AA

如果区域太短,则需要右键填充区域:left-padding会产生错误的排序顺序。所有单字母区域--B,E,G,L,M,N,S,W - 将在所有双字母区域之前排序 - AB,AL,...,ZE - 如果你左边填充< / p>

需要对区号进行填充,以确保自然的W1,W2,...,W9,W10顺序保持不变

答案 1 :(得分:2)

我知道这已经晚了几年,但我也遇到过这个问题。 我已经设法用以下代码来完成它,所以我想在我搜索互联网时分享它并找不到任何东西!

mysql_query("SELECT SUBSTRING_INDEX(postcode,' ',1) as p1, SUBSTRING_INDEX(postcode,' ',-1) as p2 from `table` ORDER BY LENGTH(p1), p1, p2 ASC");

此代码将采用完整的英国邮政编码并将其拆分为2。

然后按照邮政编码的第一部分和第二部分进行排序。

答案 2 :(得分:1)

我很想将规范化的邮政编码与真实的邮政编码一起存储在数据库中 - 这样你只需要进行一次字符串操作,就可以使用索引来帮助你进行排序。