0

我正在尝试创建一个 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。

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
4

1 回答 1

3

以下查询将获得所有结果,其中 shipping 表中的 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
于 2012-01-26T17:57:53.970 回答