MySQL - 根据一个或两个第一个字符匹配邮政编码

时间:2012-01-26 17:29:15

标签: mysql postal-code

我正在尝试创建一个SQL语句,根据提供的邮政编码和数据库中存储的邮政编码加上权重方面来查找匹配记录。

数据库中的邮政编码介于1或2个字符之间,即B,BA ......

现在 - 传递给SQL语句的值将始终包含客户端邮政编码的2个第一个字符。我怎样才能找到它的匹配?假设我有一个邮政编码B1,它只匹配数据库中的单个B加上重量方面,我很满意。

这是我当前的SQL语句,它也采用超过一定权重的免费送货因子:

SELECT `s`.*,
IF (
    '{$weight}' > (
        SELECT MAX(`weight_from`)
        FROM `shipping`
        WHERE UPPER(SUBSTRING(`post_code`, 1, 2)) = 'B1'
    ),
    (
        SELECT `cost`
        FROM `shipping`
        WHERE UPPER(SUBSTRING(`post_code`, 1, 2)) = 'B1'
        ORDER BY `weight_from` DESC
        LIMIT 0, 1
    ),
    `s`.`cost`
) AS `cost`
FROM `shipping` `s`
WHERE UPPER(SUBSTRING(`s`.`post_code`, 1, 2)) = 'B1'
AND 
(
    (
        '{$weight}' > (
            SELECT MAX(`weight_from`)
            FROM `shipping`
            WHERE UPPER(SUBSTRING(`post_code`, 1, 2)) = 'B1'
        )
    )
    OR 
    ('{$weight}' BETWEEN `s`.`weight_from` AND `s`.`weight_to`)
)
LIMIT 0, 1

然而,上面使用SUBSTRING()函数,硬编码字符数设置为2 - 这是我需要一些帮助才能使它只匹配提供的邮政编码匹配的字符数 - 在本例中为B1。

马库斯 - 感谢您的帮助 - 杰出的榜样 - 这就是我的代码对于那些也不知道的人来说的样子:

首先,我运行以下语句以获取正确的邮政编码:

(
    SELECT `post_code`
    FROM `shipping`
    WHERE `post_code` = 'B1'
)
UNION
(
    SELECT `post_code`
    FROM `shipping`
    WHERE `post_code` = SUBSTRING('B1', 1, 1)
)
ORDER BY `post_code` DESC
LIMIT 0, 1

然后,根据分配给'post_code'索引的返回值,我的第二个语句后跟:

$post_code = $result['post_code'];

SELECT `s`.*,
IF (
    '1000' > (
        SELECT MAX(`weight_from`)
        FROM `shipping`
        WHERE `post_code` = '{$post_code}'  
    ),
    (
        SELECT `cost`
        FROM `shipping`
        WHERE `post_code` = '{$post_code}'
        ORDER BY `weight_from` DESC
        LIMIT 0, 1
    ),
    `s`.`cost`
) AS `cost`
FROM `shipping` `s`
WHERE `s`.`post_code` = '{$post_code}'
AND 
(
    (
        '1000' > (
            SELECT MAX(`weight_from`)
            FROM `shipping`
            WHERE `post_code` = '{$post_code}'
            ORDER BY LENGTH(`post_code`) DESC
        )
    )
    OR 
    ('1000' BETWEEN `s`.`weight_from` AND `s`.`weight_to`)
)
LIMIT 0, 1

1 个答案:

答案 0 :(得分:2)

以下查询将获得所有结果,其中发货表中的post_code与传递的post_code的开头匹配,然后它将其最明确地命令为最不明确,返回最明确的一个:

SELECT *
FROM shipping
WHERE post_code = SUBSTRING('B1', 1, LENGTH(post_code))
ORDER BY LENGTH(post_code) DESC
LIMIT 1

<强>更新

虽然这个查询很灵活,但速度不是很快,因为它无法使用索引。如果发货表很大,并且您最多只传递两个字符,则进行两次单独的呼叫可能会更快。

首先,尝试最明确的电话。

SELECT *
FROM shipping
WHERE post_code = 'B1'

如果它没有返回结果,则搜索单个字符:

SELECT *
FROM shipping
WHERE post_code = SUBSTRING('B1', 1, 1)

当然,如果你必须在一次通话中将它们与UNION结合起来:

SELECT * FROM
((SELECT *
FROM shipping
WHERE post_code = 'B1')
UNION
(SELECT *
FROM shipping
WHERE post_code = SUBSTRING('B1', 1, 1))) a
ORDER BY post_code DESC
LIMIT 1