如何通过邮政编码订购?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过邮政编码订购?相关的知识,希望对你有一定的参考价值。
我有一份小报告,需要通过邮政编码订购。我该怎么做呢?
使用ORDER BY Postcode
返回
SK1
SK11
SK13
SK2
我怎么能回来
SK1
SK2
SK11
SK13
编辑
我应该在这个问题上添加更多内容,我正在使用整个英国的邮政编码,而不仅仅是以SK开头的邮政编码。因此,这些邮政编码中的一些将仅以1个字母开头,一些以2开头。此外,邮政编码的第二部分在列中。
假设MSSQL,并且您的Postcode字段遵循Char(2)+ Number的一致模式,那么您可以添加计算查询列:
postcode_num = convert(int,substring(postcode,3,len(postcode)))
然后用它代替Postcode进行排序:
order by postcode_num
结果如你所愿:
创建2列: 1.第一部分的VARCHAR; 2.最后(数字)部分的TINYINT。
ORDER BY postcode_prefix, postcode_suffix
资料来源:https://www.sitepoint.com/community/t/order-by-postcode/50042/9
您遇到的问题是您尝试ORDER BY的列是text类型而不是数字,因此SQL将执行您所看到的排序。相反,如果您希望SQL对它进行排序,就好像它是一个数字那么您需要对该列的“SK”部分进行子串,将数字字符转换为数字类型,然后按顺序排序。
这就是@LONG在第一条评论中回复的内容。
我接近它的方法是创建一些通用函数,在排序之前将从字符串中删除字母或数字部分。
在我的示例中,函数位于fn
模式中,因此请根据需要进行更改。
ORDER BY fn.StripToAlpha(PostCode), fn.StripToNumeric(PostCode)
这些类型的函数有很多例子,可能比我写的更有效但下面是生成我使用的函数的代码。
CREATE FUNCTION [fn].[StripToAlpha]
(
@inputString nvarchar(4000)
)
RETURNS varchar(4000)
AS
BEGIN
DECLARE @Counter as int
DECLARE @strReturnVal varchar(4000)
DECLARE @Len as int
DECLARE @ASCII as int
SET @Counter=0
SET @Len=LEN(@inputString)
SET @strReturnVal = ''
WHILE @Counter<=@Len
BEGIN
SET @Counter = @Counter +1
SET @ascii= ASCII(SUBSTRING(@inputString,@counter,1))
IF(@ascii BETWEEN 65 AND 90) OR (@ascii BETWEEN 97 AND 122)
BEGIN
SET @strReturnVal = @strReturnVal + (SUBSTRING(@inputString,@counter,1))
END
END
RETURN @strReturnVal
END
和
CREATE FUNCTION [fn].[StripToNumeric]
(
@inputString nvarchar(4000)
)
RETURNS Float
AS
BEGIN
DECLARE @Counter as int
DECLARE @strReturnVal varchar(4000)
DECLARE @ReturnVal Float
DECLARE @Len as int
DECLARE @ASCII as int
SET @Counter=0
SET @Len=LEN(@inputString)
SET @strReturnVal = ''
IF @inputString IS NULL
BEGIN
Return NULL
END
-- swap out comma for decimal
SET @inputString = REPLACE(@inputString, ',', '.')
IF @Len = 0 OR LEN(LTRIM(RTRIM(@inputString))) = 0
BEGIN
SET @ReturnVal=0
END
ELSE
BEGIN
WHILE @Counter<=@Len
BEGIN
SET @Counter = @Counter +1
SET @ascii= ASCII(SUBSTRING(@inputString,@counter,1))
IF(@ascii BETWEEN 48 AND 57) OR (@ascii IN (46,37))
BEGIN
SET @strReturnVal = @strReturnVal + (SUBSTRING(@inputString,@counter,1))
END
END
if RIGHT(@strReturnVal,1)='%'
BEGIN
SET @strReturnVal = LEFT(@strReturnVal,len(@strReturnVal)-1)
SET @strReturnVal = CAST((CAST(@strReturnVal AS FLOAT)/100) AS nvarchar(4000))
END
SET @ReturnVal = ISNULL(@strReturnVal,0)
END
RETURN @ReturnVal
END
笔记
- 这不会影响您当前的使用,但StripToNumeric检查是一个百分号,并转换为小数,因此您将它传递25%,它将返回0.25。
- 如果您使用完整的邮政编码(例如SK1 1AB),则它将无效,因为它将按SKAB排序,然后按11排序
- 它将适用于具有较短前缀的邮政编码,例如M34(如果我没记错的那就是Denton!:))
您没有指定您使用的数据库;这是一个Oracle示例。希望你能够将它“转换”成其他东西。
这个想法是:使用正则表达式(在这种情况下似乎非常方便),将邮政编码分为两部分:字母和数字。当REGEXP_SUBSTR
返回一个字符串时,我将TO_NUMBER
函数应用于邮政编码的“数字”部分,以便对其进行正确排序。
SQL> with test (postcode) as
2 (select 'sk1' from dual union
3 select 'sk11' from dual union
4 select 'sk13' from dual union
5 select 'sk2' from dual
6 )
7 select postcode
8 from test
9 order by regexp_substr(postcode, '^[[:alpha:]]+'), --> letters
10 to_number(regexp_substr(postcode, '[[:digit:]]+$')); --> numbers
POST
----
sk1
sk2
sk11
sk13
SQL>
以上是关于如何通过邮政编码订购?的主要内容,如果未能解决你的问题,请参考以下文章