MySQL-根据前一两个字符匹配帖子代码

MySQL-根据前一两个字符匹配帖子代码,mysql,postal-code,Mysql,Postal Code,我试图创建一个SQL语句,根据提供的邮政编码和数据库中存储的邮政编码以及权重方面来查找匹配的记录 数据库中的邮政编码介于1或2个字符之间,即B、B和B 现在-传递给SQL语句的值将始终具有客户端post代码的前两个字符。我怎样才能找到它的匹配项?假设我有一个邮政编码B1,它将只匹配数据库中的单个B加上权重方面,我同意 下面是我当前的SQL语句,它还考虑了超过一定重量的免费送货因素: SELECT `s`.*, IF ( '{$weight}' > ( SELECT

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

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

现在-传递给SQL语句的值将始终具有客户端post代码的前两个字符。我怎样才能找到它的匹配项?假设我有一个邮政编码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

Marcus-感谢您的帮助-杰出的示例-下面是我的代码的样子,让那些同样好奇的人看看:

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

(
    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

下面的查询将获得shipping表中的post_代码与传入的post_代码开头匹配的所有结果,然后将其从最显式排序为最不显式,并返回最显式的结果:

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

虽然这个查询很灵活,但速度不是很快,因为它不能利用索引。如果shipping表很大,并且最多只传入两个字符,则进行两次单独调用可能会更快

首先,尝试最显式的调用

SELECT *
FROM shipping
WHERE post_code = 'B1'
如果未返回结果,则搜索单个字符:

SELECT *
FROM shipping
WHERE post_code = SUBSTRING('B1', 1, 1)
当然,如果必须在一次通话中完成,您可以将这些功能与工会结合使用:

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

谢谢马库斯,我马上就去试一试,看看效果如何。