2012-01-26 2 views
0

Я пытаюсь создать инструкцию SQL, чтобы найти соответствующую запись на основе предоставленного почтового индекса и сохраненных почтовых кодов в базе данных плюс весовой аспект.MySQL - сопоставление почтового кода на основе одного или двух первых символов

Почтовые индексы в базе данных находятся между 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 

ответ

2

следующий запрос получит все результаты, где post_ код в таблице доставки соответствует началу переданного в post_code, то он заказывает это наиболее явно наименее явный, возвращая наиболее явные один:

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

Update

Хотя этот запрос является гибким, это не очень быстро, поскольку он не может использовать индекс. Если таблица доставки является большой, и вы будете передавать только до двух символов, возможно, будет быстрее сделать два отдельных вызова.

Сначала попробуйте наиболее явный вызов.

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 
+0

Thanks Marcus - Я дам ему шаг в секунду и посмотрю, как это происходит. – user398341

+0

Маркус - ты гений! – user398341

Смежные вопросы