2012-01-26 12 views
0

データベースに格納されたポストコードと重み付きアスペクトに基づいて一致するレコードを見つけるSQL文を作成しようとしています。MySQL - 1〜2文字の最初の文字に基づいたポストコード

、データベース内のポストコードは今...、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 

以上が2に設定された文字のハードコード化された番号でSUBSTRING()関数を使用しています - この提供されたポストコード(この場合は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 

答えて

2

次のクエリでは、post_すべての結果を取得します出荷表内のコードがpost_codeに渡されたの先頭にマッチし、それが最も明確なものを返す、明示的な最小にそれが最も明示的な順序付け:

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

更新

このクエリは柔軟性がありますが、それはインデックスを利用することができないので、それほど高速ではありません。配送テーブルが大きく、2文字までしか渡さない場合は、2回の別の通話を行う方が速い場合があります。

まず、最も明示的な呼び出しを試みます。

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

マーカスありがとうございました - 私はそれをもう一度行って、それがどうなるか見てみましょう。 – user398341

+0

マーカス - あなたは天才だ! – user398341

関連する問題