2012-05-10 54 views
0

我確定解決方案非常簡單,但是我的大腦今天似乎並沒有處於正確的狀態。我有一個存儲我的產品定價矩陣的MySQL表。PHP/MySQL價格矩陣表格驗證

ID  PRODUCT  MINIMUM  PRICE 
1  1   2   15 
2  1   4   12 
3  1   6   10 

那麼的簡單說明,對於id爲1的產品,如果客戶有2的最低數量在他們的購物籃中每個項目的價格買了下來£15。如果用戶再放2件產品,他們的籃子價格將降至12英鎊。

問題:我需要一種驗證新價格層的方法,每次添加一個。所以,如果有人想添加一個新的層次:

ID  PRODUCT  MINIMUM  PRICE 
4  1   3   16 

這不應該被允許在這種情況下,如果用戶選擇購買的三個項目,而不是兩個每個項目的價格會增加。所以我需要確保輸入的價格隨着數量的增加而減少,這取決於數據庫中已有的價值。

$query = 'select id,minimum,price from `cat.tier_price` where product = %d order by minimum asc;'; 
$query = sprintf($query, (int)$identity); 
if(!$return = $db->query($query)){ 
    echo 'MySQL error!'; 
}else{ 
    $quantity = $_POST['quantity']; 
    $price = $_POST['quantity']; 

    if($return->num_row){ 
     while($tier = $return->fetch_object){ 

     } 
    } 
} 

如果我沒有足夠清楚,請說說。任何幫助將不勝感激。

+0

[驗證最小。 3]獲取現有最小值低於3(這裏:2),並檢查給定價格是否小於與此處相關的最小值。 2(= 15) – djot

回答

0

這可以通過一個簡單的函數來完成:

function validateTier($productId, $minimum, $price) { 
    // check if the new tier is not higher price for higher minimum 
    $query = 'SELECT 1 AS exists FROM `cat.tier_price` WHERE `product` = {$productId} AND `minimum` < {$minimum} AND `price` > {$price} ORDER BY `minimum` DESC LIMIT 1'; 
    $res = mysql_query($query); 
    $result = mysql_fetch_assoc($res); 

    if(isset($result['exists']) && $result['exists']) { 
     // check if the new tier is not lower price for lower minimum 
     $query = 'SELECT 1 AS exists FROM `cat.tier_price` WHERE `product` = {$productId} AND `minimum` > {$minimum} AND `price` < {$price} ORDER BY `minimum` ASC LIMIT 1'; 
     $res2 = mysql_query($query); 
     $result2 = mysql_fetch_assoc($res2); 

     if(isset($result2['exists']) && $result2['exists']) return true; 
    } 

    return false; 
} 

然後,您可以調用此函數時,應增加一個新的層次。該函數試圖精確選擇一條記錄,其中最小值低於插入的記錄,並且價格高於插入的記錄。如果這個查詢成功,它將返回1(被認爲是真的),這意味着可能會插入新的撕裂。否則,將返回FALSE,這意味着新層不正確。

但我認爲這也應該做一個伎倆(更簡單):

function validateTier($productId, $minimum, $price) { 
    // check if the new tier is not higher price for higher minimum 
    $query = 'SELECT 1 AS exists FROM `cat.tier_price` WHERE `product` = {$productId} AND ((`minimum` < {$minimum} AND `price` > {$price}) OR (`minimum` > {$minimum} AND `price` < {$price})) LIMIT 1'; 
    $res = mysql_query($query); 
    $result = mysql_fetch_assoc($res); 

    if(isset($result['exists']) && $result['exists']) return true; 

    return false; 
} 

請讓我知道,如果這也適用。

+0

爲此歡呼,這適用於「3,16」。但是如果我試圖「3,11」這應該也不會被允許的價格比價格最低的4款產品更低?道歉上述那是我的錯,我沒有提到這一點。 – Adam

+0

@Adam我編輯的功能,現在它不應該讓沒有更低的價格與較低的最低比一個已經裏三層外三層... – shadyyx

+0

謝謝大家我從來沒有見過如此輝煌的一套應對的問題。我的大腦現在有點暖和了,非常感謝。 – Adam

0

對於這種數據驗證,您應該在操作完成之前使用一個trigger錯誤(例如通過調用不存在的過程)來處理無效數據;正因爲如此,MySQL的將中止任何試圖插入無效數據:

DELIMITER ;; 

CREATE TRIGGER foo BEFORE INSERT ON tier_price FOR EACH ROW 
    IF (
    SELECT COUNT(*) 
    FROM tier_price 
    WHERE product = NEW.product 
     AND (
       (minimum > NEW.minimum AND price > NEW.price) 
      OR (minimum < NEW.minimum AND price < NEW.price) 
     ) 
) > 0 THEN 
    CALL raise_error; 
    END IF;; 

DELIMITER ; 

如果tier_price記錄也可能會更新,你可能需要一個類似的觸發器BEFORE UPDATE了。

+0

這是一個我以前沒有考慮過的有趣的方法。我目前收到錯誤: 不允許從觸發器返回結果集 – Adam

+0

@Adam:這會教我嘗試過度優化。看到我上面回滾的版本。 – eggyal

+0

謝謝大家,我從來沒有見過如此輝煌的回答一個問題。我的大腦現在有點暖和了,非常感謝。 – Adam

0

我會以相反的方式做到這一點。它將處理price_matrix表中沒有給定product_id的情況。

set @product_id := 1; 
    set @minimum :=3; 
    set @price :=16; 

    select count(*) as count from price_matrix where product_id = @product_id and 
    (
     (minimum > @minimum and price > @price) 
     or 
     (minimum < @minimum and price < @price) 
    ) 

    If count > 0: 
     This entry is not permitted 
    else : 
     Permitted 
+0

謝謝大家我從來沒有見過如此輝煌的一套應對的問題。我的大腦現在有點暖和了,非常感謝。 – Adam