首页 > 解决方案 > 比较两个字母数字mysql列(查找范围之间的邮政编码区)

问题描述

我有一个 mysql 数据库,其中包含一系列邮政编码区范围。我试图找到与给定区域匹配的行,在本例中为“SY18”。我在下面有 mysql 查询,但它返回表中的两个值,因为这些字段是字母数字的。

SELECT rate FROM table WHERE district_from <= 'SY18' AND district_to >= 'SY18'

表格示例

id    district_from    district_to    rate
1     SY1              SY9            10
2     SY16             SY22           20
3     AL1              AL99           37
4     B1               B99            37
5     BB1              BB99           37
6     CB1              CB99           40

如何只返回正确的结果?

标签: mysqlpostal-code

解决方案


CREATE FUNCTION normalize_district (district VARCHAR(4))
RETURNS VARCHAR(4) DETERMINISTIC
RETURN CONCAT( TRIM(TRAILING CASE WHEN 0 + RIGHT(district, 2) > 0 
                                  THEN RIGHT(district, 2)
                                  ELSE RIGHT(district, 1) END FROM district),
               LPAD(CASE WHEN 0 + RIGHT(district, 2) > 0 
                         THEN 0 + RIGHT(district, 2)
                         ELSE 0 + RIGHT(district, 1) END, 2, '0') );

接着

SELECT *
FROM district_to_test
LEFT JOIN rate ON normalize_district(district_to_test.district) 
                         BETWEEN normalize_district(district_from)
                             AND normalize_district(district_to);

小提琴


0 + RIGHT(district, 2) > 0在函数 thecks 中,最后 2 个符号district是数字。

如果为真,那么 RIGHT() 将提取 2 位数字,并且整个表达式值将高于零(您声称没有类似'AA0'or的值'AA00')。

如果为假,并且只存在一位数字,则 RIGHT() 将给出一个以字母开头的子字符串,该值将为零。

基于此,我将整个值划分为前缀和数字后缀,并在数字部分添加零,使其无条件为 2 位。该值可用于 BETWEEN 运算符的直接字符串比较。


函数的目标是将值转换为'AA00'格式。为此,我们必须将整个值划分为文本和数字部分,并对后者进行规范化(零填充)。

您可以使用任何其他划分方法。例如,您可以使用 . 检查值是否包含两位数LIKE '%\\d\\d'。或者向后,您可以使用...确定该值是否包含两个字母LIKE '\\D\\D%',这些方法的难度相对相等。


推荐阅读